diff --git a/androidx/multidex/MultiDex.java b/androidx/multidex/MultiDex.java
new file mode 100644
index 0000000..c038709
--- /dev/null
+++ b/androidx/multidex/MultiDex.java
@@ -0,0 +1,783 @@
+/*
+ * Copyright (C) 2013 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 androidx.multidex;
+
+import android.app.Application;
+import android.app.Instrumentation;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.os.Build;
+import android.util.Log;
+
+import dalvik.system.DexFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.zip.ZipFile;
+
+/**
+ * MultiDex patches {@link Context#getClassLoader() the application context class
+ * loader} in order to load classes from more than one dex file. The primary
+ * {@code classes.dex} must contain the classes necessary for calling this
+ * class methods. Secondary dex files named classes2.dex, classes3.dex... found
+ * in the application apk will be added to the classloader after first call to
+ * {@link #install(Context)}.
+ *
+ * <p/>
+ * This library provides compatibility for platforms with API level 4 through 20. This library does
+ * nothing on newer versions of the platform which provide built-in support for secondary dex files.
+ */
+public final class MultiDex {
+
+    static final String TAG = "MultiDex";
+
+    private static final String OLD_SECONDARY_FOLDER_NAME = "secondary-dexes";
+
+    private static final String CODE_CACHE_NAME = "code_cache";
+
+    private static final String CODE_CACHE_SECONDARY_FOLDER_NAME = "secondary-dexes";
+
+    private static final int MAX_SUPPORTED_SDK_VERSION = 20;
+
+    private static final int MIN_SDK_VERSION = 4;
+
+    private static final int VM_WITH_MULTIDEX_VERSION_MAJOR = 2;
+
+    private static final int VM_WITH_MULTIDEX_VERSION_MINOR = 1;
+
+    private static final String NO_KEY_PREFIX = "";
+
+    private static final Set<File> installedApk = new HashSet<File>();
+
+    private static final boolean IS_VM_MULTIDEX_CAPABLE =
+            isVMMultidexCapable(System.getProperty("java.vm.version"));
+
+    private MultiDex() {}
+
+    /**
+     * Patches the application context class loader by appending extra dex files
+     * loaded from the application apk. This method should be called in the
+     * attachBaseContext of your {@link Application}, see
+     * {@link MultiDexApplication} for more explanation and an example.
+     *
+     * @param context application context.
+     * @throws RuntimeException if an error occurred preventing the classloader
+     *         extension.
+     */
+    public static void install(Context context) {
+        Log.i(TAG, "Installing application");
+        if (IS_VM_MULTIDEX_CAPABLE) {
+            Log.i(TAG, "VM has multidex support, MultiDex support library is disabled.");
+            return;
+        }
+
+        if (Build.VERSION.SDK_INT < MIN_SDK_VERSION) {
+            throw new RuntimeException("MultiDex installation failed. SDK " + Build.VERSION.SDK_INT
+                    + " is unsupported. Min SDK version is " + MIN_SDK_VERSION + ".");
+        }
+
+        try {
+            ApplicationInfo applicationInfo = getApplicationInfo(context);
+            if (applicationInfo == null) {
+              Log.i(TAG, "No ApplicationInfo available, i.e. running on a test Context:"
+                  + " MultiDex support library is disabled.");
+              return;
+            }
+
+            doInstallation(context,
+                    new File(applicationInfo.sourceDir),
+                    new File(applicationInfo.dataDir),
+                    CODE_CACHE_SECONDARY_FOLDER_NAME,
+                    NO_KEY_PREFIX,
+                    true);
+
+        } catch (Exception e) {
+            Log.e(TAG, "MultiDex installation failure", e);
+            throw new RuntimeException("MultiDex installation failed (" + e.getMessage() + ").");
+        }
+        Log.i(TAG, "install done");
+    }
+
+    /**
+     * Patches the instrumentation context class loader by appending extra dex files
+     * loaded from the instrumentation apk and the application apk. This method should be called in
+     * the onCreate of your {@link Instrumentation}, see
+     * {@link com.android.test.runner.MultiDexTestRunner} for an example.
+     *
+     * @param instrumentationContext instrumentation context.
+     * @param targetContext target application context.
+     * @throws RuntimeException if an error occurred preventing the classloader
+     *         extension.
+     */
+    public static void installInstrumentation(Context instrumentationContext,
+            Context targetContext) {
+        Log.i(TAG, "Installing instrumentation");
+
+        if (IS_VM_MULTIDEX_CAPABLE) {
+            Log.i(TAG, "VM has multidex support, MultiDex support library is disabled.");
+            return;
+        }
+
+        if (Build.VERSION.SDK_INT < MIN_SDK_VERSION) {
+            throw new RuntimeException("MultiDex installation failed. SDK " + Build.VERSION.SDK_INT
+                    + " is unsupported. Min SDK version is " + MIN_SDK_VERSION + ".");
+        }
+        try {
+
+            ApplicationInfo instrumentationInfo = getApplicationInfo(instrumentationContext);
+            if (instrumentationInfo == null) {
+                Log.i(TAG, "No ApplicationInfo available for instrumentation, i.e. running on a"
+                    + " test Context: MultiDex support library is disabled.");
+                return;
+            }
+
+            ApplicationInfo applicationInfo = getApplicationInfo(targetContext);
+            if (applicationInfo == null) {
+                Log.i(TAG, "No ApplicationInfo available, i.e. running on a test Context:"
+                    + " MultiDex support library is disabled.");
+                return;
+            }
+
+            String instrumentationPrefix = instrumentationContext.getPackageName() + ".";
+
+            File dataDir = new File(applicationInfo.dataDir);
+
+            doInstallation(targetContext,
+                    new File(instrumentationInfo.sourceDir),
+                    dataDir,
+                    instrumentationPrefix + CODE_CACHE_SECONDARY_FOLDER_NAME,
+                    instrumentationPrefix,
+                    false);
+
+            doInstallation(targetContext,
+                    new File(applicationInfo.sourceDir),
+                    dataDir,
+                    CODE_CACHE_SECONDARY_FOLDER_NAME,
+                    NO_KEY_PREFIX,
+                    false);
+        } catch (Exception e) {
+            Log.e(TAG, "MultiDex installation failure", e);
+            throw new RuntimeException("MultiDex installation failed (" + e.getMessage() + ").");
+        }
+        Log.i(TAG, "Installation done");
+    }
+
+    /**
+     * @param mainContext context used to get filesDir, to save preference and to get the
+     * classloader to patch.
+     * @param sourceApk Apk file.
+     * @param dataDir data directory to use for code cache simulation.
+     * @param secondaryFolderName name of the folder for storing extractions.
+     * @param prefsKeyPrefix prefix of all stored preference keys.
+     * @param reinstallOnPatchRecoverableException if set to true, will attempt a clean extraction
+     * if a possibly recoverable exception occurs during classloader patching.
+     */
+    private static void doInstallation(Context mainContext, File sourceApk, File dataDir,
+            String secondaryFolderName, String prefsKeyPrefix,
+            boolean reinstallOnPatchRecoverableException) throws IOException,
+                IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
+                InvocationTargetException, NoSuchMethodException, SecurityException,
+                ClassNotFoundException, InstantiationException {
+        synchronized (installedApk) {
+            if (installedApk.contains(sourceApk)) {
+                return;
+            }
+            installedApk.add(sourceApk);
+
+            if (Build.VERSION.SDK_INT > MAX_SUPPORTED_SDK_VERSION) {
+                Log.w(TAG, "MultiDex is not guaranteed to work in SDK version "
+                        + Build.VERSION.SDK_INT + ": SDK version higher than "
+                        + MAX_SUPPORTED_SDK_VERSION + " should be backed by "
+                        + "runtime with built-in multidex capabilty but it's not the "
+                        + "case here: java.vm.version=\""
+                        + System.getProperty("java.vm.version") + "\"");
+            }
+
+            /* The patched class loader is expected to be a ClassLoader capable of loading DEX
+             * bytecode. We modify its pathList field to append additional DEX file entries.
+             */
+            ClassLoader loader = getDexClassloader(mainContext);
+            if (loader == null) {
+                return;
+            }
+
+            try {
+              clearOldDexDir(mainContext);
+            } catch (Throwable t) {
+              Log.w(TAG, "Something went wrong when trying to clear old MultiDex extraction, "
+                  + "continuing without cleaning.", t);
+            }
+
+            File dexDir = getDexDir(mainContext, dataDir, secondaryFolderName);
+            // MultiDexExtractor is taking the file lock and keeping it until it is closed.
+            // Keep it open during installSecondaryDexes and through forced extraction to ensure no
+            // extraction or optimizing dexopt is running in parallel.
+            MultiDexExtractor extractor = new MultiDexExtractor(sourceApk, dexDir);
+            IOException closeException = null;
+            try {
+                List<? extends File> files =
+                        extractor.load(mainContext, prefsKeyPrefix, false);
+                try {
+                    installSecondaryDexes(loader, dexDir, files);
+                // Some IOException causes may be fixed by a clean extraction.
+                } catch (IOException e) {
+                    if (!reinstallOnPatchRecoverableException) {
+                        throw e;
+                    }
+                    Log.w(TAG, "Failed to install extracted secondary dex files, retrying with "
+                            + "forced extraction", e);
+                    files = extractor.load(mainContext, prefsKeyPrefix, true);
+                    installSecondaryDexes(loader, dexDir, files);
+                }
+            } finally {
+                try {
+                    extractor.close();
+                } catch (IOException e) {
+                    // Delay throw of close exception to ensure we don't override some exception
+                    // thrown during the try block.
+                    closeException = e;
+                }
+            }
+            if (closeException != null) {
+                throw closeException;
+            }
+        }
+    }
+
+    /**
+     * Returns a {@link Classloader} from the {@link Context} that is capable of reading dex
+     * bytecode or null if the Classloader is not dex-capable e.g: when running on a JVM testing
+     * environment such as Robolectric.
+     */
+    private static ClassLoader getDexClassloader(Context context) {
+        ClassLoader loader;
+        try {
+            loader = context.getClassLoader();
+        } catch (RuntimeException e) {
+            /* Ignore those exceptions so that we don't break tests relying on Context like
+             * a android.test.mock.MockContext or a android.content.ContextWrapper with a
+             * null base Context.
+             */
+            Log.w(TAG, "Failure while trying to obtain Context class loader. "
+                    + "Must be running in test mode. Skip patching.", e);
+            return null;
+        }
+
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            if (loader instanceof dalvik.system.BaseDexClassLoader) {
+                return loader;
+            }
+        } else if (loader instanceof dalvik.system.DexClassLoader
+                    || loader instanceof dalvik.system.PathClassLoader) {
+            return loader;
+        }
+        Log.e(TAG, "Context class loader is null or not dex-capable. "
+                + "Must be running in test mode. Skip patching.");
+        return null;
+    }
+
+    private static ApplicationInfo getApplicationInfo(Context context) {
+        try {
+            /* Due to package install races it is possible for a process to be started from an old
+             * apk even though that apk has been replaced. Querying for ApplicationInfo by package
+             * name may return information for the new apk, leading to a runtime with the old main
+             * dex file and new secondary dex files. This leads to various problems like
+             * ClassNotFoundExceptions. Using context.getApplicationInfo() should result in the
+             * process having a consistent view of the world (even if it is of the old world). The
+             * package install races are eventually resolved and old processes are killed.
+             */
+            return context.getApplicationInfo();
+        } catch (RuntimeException e) {
+            /* Ignore those exceptions so that we don't break tests relying on Context like
+             * a android.test.mock.MockContext or a android.content.ContextWrapper with a null
+             * base Context.
+             */
+            Log.w(TAG, "Failure while trying to obtain ApplicationInfo from Context. " +
+                    "Must be running in test mode. Skip patching.", e);
+            return null;
+        }
+    }
+
+    /**
+     * Identifies if the current VM has a native support for multidex, meaning there is no need for
+     * additional installation by this library.
+     * @return true if the VM handles multidex
+     */
+    /* package visible for test */
+    static boolean isVMMultidexCapable(String versionString) {
+        boolean isMultidexCapable = false;
+        if (versionString != null) {
+            StringTokenizer tokenizer = new StringTokenizer(versionString, ".");
+            String majorToken = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
+            String minorToken = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : null;
+            if (majorToken != null && minorToken != null) {
+                try {
+                    int major = Integer.parseInt(majorToken);
+                    int minor = Integer.parseInt(minorToken);
+                    isMultidexCapable = (major > VM_WITH_MULTIDEX_VERSION_MAJOR)
+                            || ((major == VM_WITH_MULTIDEX_VERSION_MAJOR)
+                                    && (minor >= VM_WITH_MULTIDEX_VERSION_MINOR));
+                } catch (NumberFormatException e) {
+                    // let isMultidexCapable be false
+                }
+            }
+        }
+        Log.i(TAG, "VM with version " + versionString +
+                (isMultidexCapable ?
+                        " has multidex support" :
+                        " does not have multidex support"));
+        return isMultidexCapable;
+    }
+
+    private static void installSecondaryDexes(ClassLoader loader, File dexDir,
+        List<? extends File> files)
+            throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException,
+            InvocationTargetException, NoSuchMethodException, IOException, SecurityException,
+            ClassNotFoundException, InstantiationException {
+        if (!files.isEmpty()) {
+            if (Build.VERSION.SDK_INT >= 19) {
+                V19.install(loader, files, dexDir);
+            } else if (Build.VERSION.SDK_INT >= 14) {
+                V14.install(loader, files);
+            } else {
+                V4.install(loader, files);
+            }
+        }
+    }
+
+    /**
+     * Locates a given field anywhere in the class inheritance hierarchy.
+     *
+     * @param instance an object to search the field into.
+     * @param name field name
+     * @return a field object
+     * @throws NoSuchFieldException if the field cannot be located
+     */
+    private static Field findField(Object instance, String name) throws NoSuchFieldException {
+        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+            try {
+                Field field = clazz.getDeclaredField(name);
+
+
+                if (!field.isAccessible()) {
+                    field.setAccessible(true);
+                }
+
+                return field;
+            } catch (NoSuchFieldException e) {
+                // ignore and search next
+            }
+        }
+
+        throw new NoSuchFieldException("Field " + name + " not found in " + instance.getClass());
+    }
+
+    /**
+     * Locates a given method anywhere in the class inheritance hierarchy.
+     *
+     * @param instance an object to search the method into.
+     * @param name method name
+     * @param parameterTypes method parameter types
+     * @return a method object
+     * @throws NoSuchMethodException if the method cannot be located
+     */
+    private static Method findMethod(Object instance, String name, Class<?>... parameterTypes)
+            throws NoSuchMethodException {
+        for (Class<?> clazz = instance.getClass(); clazz != null; clazz = clazz.getSuperclass()) {
+            try {
+                Method method = clazz.getDeclaredMethod(name, parameterTypes);
+
+
+                if (!method.isAccessible()) {
+                    method.setAccessible(true);
+                }
+
+                return method;
+            } catch (NoSuchMethodException e) {
+                // ignore and search next
+            }
+        }
+
+        throw new NoSuchMethodException("Method " + name + " with parameters " +
+                Arrays.asList(parameterTypes) + " not found in " + instance.getClass());
+    }
+
+    /**
+     * Replace the value of a field containing a non null array, by a new array containing the
+     * elements of the original array plus the elements of extraElements.
+     * @param instance the instance whose field is to be modified.
+     * @param fieldName the field to modify.
+     * @param extraElements elements to append at the end of the array.
+     */
+    private static void expandFieldArray(Object instance, String fieldName,
+            Object[] extraElements) throws NoSuchFieldException, IllegalArgumentException,
+            IllegalAccessException {
+        Field jlrField = findField(instance, fieldName);
+        Object[] original = (Object[]) jlrField.get(instance);
+        Object[] combined = (Object[]) Array.newInstance(
+                original.getClass().getComponentType(), original.length + extraElements.length);
+        System.arraycopy(original, 0, combined, 0, original.length);
+        System.arraycopy(extraElements, 0, combined, original.length, extraElements.length);
+        jlrField.set(instance, combined);
+    }
+
+    private static void clearOldDexDir(Context context) throws Exception {
+        File dexDir = new File(context.getFilesDir(), OLD_SECONDARY_FOLDER_NAME);
+        if (dexDir.isDirectory()) {
+            Log.i(TAG, "Clearing old secondary dex dir (" + dexDir.getPath() + ").");
+            File[] files = dexDir.listFiles();
+            if (files == null) {
+                Log.w(TAG, "Failed to list secondary dex dir content (" + dexDir.getPath() + ").");
+                return;
+            }
+            for (File oldFile : files) {
+                Log.i(TAG, "Trying to delete old file " + oldFile.getPath() + " of size "
+                        + oldFile.length());
+                if (!oldFile.delete()) {
+                    Log.w(TAG, "Failed to delete old file " + oldFile.getPath());
+                } else {
+                    Log.i(TAG, "Deleted old file " + oldFile.getPath());
+                }
+            }
+            if (!dexDir.delete()) {
+                Log.w(TAG, "Failed to delete secondary dex dir " + dexDir.getPath());
+            } else {
+                Log.i(TAG, "Deleted old secondary dex dir " + dexDir.getPath());
+            }
+        }
+    }
+
+    private static File getDexDir(Context context, File dataDir, String secondaryFolderName)
+            throws IOException {
+        File cache = new File(dataDir, CODE_CACHE_NAME);
+        try {
+            mkdirChecked(cache);
+        } catch (IOException e) {
+            /* If we can't emulate code_cache, then store to filesDir. This means abandoning useless
+             * files on disk if the device ever updates to android 5+. But since this seems to
+             * happen only on some devices running android 2, this should cause no pollution.
+             */
+            cache = new File(context.getFilesDir(), CODE_CACHE_NAME);
+            mkdirChecked(cache);
+        }
+        File dexDir = new File(cache, secondaryFolderName);
+        mkdirChecked(dexDir);
+        return dexDir;
+    }
+
+    private static void mkdirChecked(File dir) throws IOException {
+        dir.mkdir();
+        if (!dir.isDirectory()) {
+            File parent = dir.getParentFile();
+            if (parent == null) {
+                Log.e(TAG, "Failed to create dir " + dir.getPath() + ". Parent file is null.");
+            } else {
+                Log.e(TAG, "Failed to create dir " + dir.getPath() +
+                        ". parent file is a dir " + parent.isDirectory() +
+                        ", a file " + parent.isFile() +
+                        ", exists " + parent.exists() +
+                        ", readable " + parent.canRead() +
+                        ", writable " + parent.canWrite());
+            }
+            throw new IOException("Failed to create directory " + dir.getPath());
+        }
+    }
+
+    /**
+     * Installer for platform versions 19.
+     */
+    private static final class V19 {
+
+        static void install(ClassLoader loader,
+                List<? extends File> additionalClassPathEntries,
+                File optimizedDirectory)
+                        throws IllegalArgumentException, IllegalAccessException,
+                        NoSuchFieldException, InvocationTargetException, NoSuchMethodException,
+                        IOException {
+            /* The patched class loader is expected to be a descendant of
+             * dalvik.system.BaseDexClassLoader. We modify its
+             * dalvik.system.DexPathList pathList field to append additional DEX
+             * file entries.
+             */
+            Field pathListField = findField(loader, "pathList");
+            Object dexPathList = pathListField.get(loader);
+            ArrayList<IOException> suppressedExceptions = new ArrayList<IOException>();
+            expandFieldArray(dexPathList, "dexElements", makeDexElements(dexPathList,
+                    new ArrayList<File>(additionalClassPathEntries), optimizedDirectory,
+                    suppressedExceptions));
+            if (suppressedExceptions.size() > 0) {
+                for (IOException e : suppressedExceptions) {
+                    Log.w(TAG, "Exception in makeDexElement", e);
+                }
+                Field suppressedExceptionsField =
+                        findField(dexPathList, "dexElementsSuppressedExceptions");
+                IOException[] dexElementsSuppressedExceptions =
+                        (IOException[]) suppressedExceptionsField.get(dexPathList);
+
+                if (dexElementsSuppressedExceptions == null) {
+                    dexElementsSuppressedExceptions =
+                            suppressedExceptions.toArray(
+                                    new IOException[suppressedExceptions.size()]);
+                } else {
+                    IOException[] combined =
+                            new IOException[suppressedExceptions.size() +
+                                            dexElementsSuppressedExceptions.length];
+                    suppressedExceptions.toArray(combined);
+                    System.arraycopy(dexElementsSuppressedExceptions, 0, combined,
+                            suppressedExceptions.size(), dexElementsSuppressedExceptions.length);
+                    dexElementsSuppressedExceptions = combined;
+                }
+
+                suppressedExceptionsField.set(dexPathList, dexElementsSuppressedExceptions);
+
+                IOException exception = new IOException("I/O exception during makeDexElement");
+                exception.initCause(suppressedExceptions.get(0));
+                throw exception;
+            }
+        }
+
+        /**
+         * A wrapper around
+         * {@code private static final dalvik.system.DexPathList#makeDexElements}.
+         */
+        private static Object[] makeDexElements(
+                Object dexPathList, ArrayList<File> files, File optimizedDirectory,
+                ArrayList<IOException> suppressedExceptions)
+                        throws IllegalAccessException, InvocationTargetException,
+                        NoSuchMethodException {
+            Method makeDexElements =
+                    findMethod(dexPathList, "makeDexElements", ArrayList.class, File.class,
+                            ArrayList.class);
+
+            return (Object[]) makeDexElements.invoke(dexPathList, files, optimizedDirectory,
+                    suppressedExceptions);
+        }
+    }
+
+    /**
+     * Installer for platform versions 14, 15, 16, 17 and 18.
+     */
+    private static final class V14 {
+
+        private interface ElementConstructor {
+            Object newInstance(File file, DexFile dex)
+                    throws IllegalArgumentException, InstantiationException,
+                    IllegalAccessException, InvocationTargetException, IOException;
+        }
+
+        /**
+         * Applies for ICS and early JB (initial release and MR1).
+         */
+        private static class ICSElementConstructor implements ElementConstructor {
+            private final Constructor<?> elementConstructor;
+
+            ICSElementConstructor(Class<?> elementClass)
+                    throws SecurityException, NoSuchMethodException {
+                elementConstructor =
+                        elementClass.getConstructor(File.class, ZipFile.class, DexFile.class);
+                elementConstructor.setAccessible(true);
+            }
+
+            @Override
+            public Object newInstance(File file, DexFile dex)
+                    throws IllegalArgumentException, InstantiationException,
+                    IllegalAccessException, InvocationTargetException, IOException {
+                return elementConstructor.newInstance(file, new ZipFile(file), dex);
+            }
+        }
+
+        /**
+         * Applies for some intermediate JB (MR1.1).
+         *
+         * See Change-Id: I1a5b5d03572601707e1fb1fd4424c1ae2fd2217d
+         */
+        private static class JBMR11ElementConstructor implements ElementConstructor {
+            private final Constructor<?> elementConstructor;
+
+            JBMR11ElementConstructor(Class<?> elementClass)
+                    throws SecurityException, NoSuchMethodException {
+                elementConstructor = elementClass
+                        .getConstructor(File.class, File.class, DexFile.class);
+                elementConstructor.setAccessible(true);
+            }
+
+            @Override
+            public Object newInstance(File file, DexFile dex)
+                    throws IllegalArgumentException, InstantiationException,
+                    IllegalAccessException, InvocationTargetException {
+                return elementConstructor.newInstance(file, file, dex);
+            }
+        }
+
+        /**
+         * Applies for latest JB (MR2).
+         *
+         * See Change-Id: Iec4dca2244db9c9c793ac157e258fd61557a7a5d
+         */
+        private static class JBMR2ElementConstructor implements ElementConstructor {
+            private final Constructor<?> elementConstructor;
+
+            JBMR2ElementConstructor(Class<?> elementClass)
+                    throws SecurityException, NoSuchMethodException {
+                elementConstructor = elementClass
+                        .getConstructor(File.class, Boolean.TYPE, File.class, DexFile.class);
+                elementConstructor.setAccessible(true);
+            }
+
+            @Override
+            public Object newInstance(File file, DexFile dex)
+                    throws IllegalArgumentException, InstantiationException,
+                    IllegalAccessException, InvocationTargetException {
+                return elementConstructor.newInstance(file, Boolean.FALSE, file, dex);
+            }
+        }
+
+        private static final int EXTRACTED_SUFFIX_LENGTH =
+                MultiDexExtractor.EXTRACTED_SUFFIX.length();
+
+        private final ElementConstructor elementConstructor;
+
+        static void install(ClassLoader loader,
+                List<? extends File> additionalClassPathEntries)
+                        throws  IOException, SecurityException, IllegalArgumentException,
+                        ClassNotFoundException, NoSuchMethodException, InstantiationException,
+                        IllegalAccessException, InvocationTargetException, NoSuchFieldException {
+            /* The patched class loader is expected to be a descendant of
+             * dalvik.system.BaseDexClassLoader. We modify its
+             * dalvik.system.DexPathList pathList field to append additional DEX
+             * file entries.
+             */
+            Field pathListField = findField(loader, "pathList");
+            Object dexPathList = pathListField.get(loader);
+            Object[] elements = new V14().makeDexElements(additionalClassPathEntries);
+            try {
+                expandFieldArray(dexPathList, "dexElements", elements);
+            } catch (NoSuchFieldException e) {
+                // dexElements was renamed pathElements for a short period during JB development,
+                // eventually it was renamed back shortly after.
+                Log.w(TAG, "Failed find field 'dexElements' attempting 'pathElements'", e);
+                expandFieldArray(dexPathList, "pathElements", elements);
+            }
+        }
+
+        private  V14() throws ClassNotFoundException, SecurityException, NoSuchMethodException {
+            ElementConstructor constructor;
+            Class<?> elementClass = Class.forName("dalvik.system.DexPathList$Element");
+            try {
+                constructor = new ICSElementConstructor(elementClass);
+            } catch (NoSuchMethodException e1) {
+                try {
+                    constructor = new JBMR11ElementConstructor(elementClass);
+                } catch (NoSuchMethodException e2) {
+                    constructor = new JBMR2ElementConstructor(elementClass);
+                }
+            }
+            this.elementConstructor = constructor;
+        }
+
+        /**
+         * An emulation of {@code private static final dalvik.system.DexPathList#makeDexElements}
+         * accepting only extracted secondary dex files.
+         * OS version is catching IOException and just logging some of them, this version is letting
+         * them through.
+         */
+        private Object[] makeDexElements(List<? extends File> files)
+                throws IOException, SecurityException, IllegalArgumentException,
+                InstantiationException, IllegalAccessException, InvocationTargetException {
+            Object[] elements = new Object[files.size()];
+            for (int i = 0; i < elements.length; i++) {
+                File file = files.get(i);
+                elements[i] = elementConstructor.newInstance(
+                        file,
+                        DexFile.loadDex(file.getPath(), optimizedPathFor(file), 0));
+            }
+            return elements;
+        }
+
+        /**
+         * Converts a zip file path of an extracted secondary dex to an output file path for an
+         * associated optimized dex file.
+         */
+        private static String optimizedPathFor(File path) {
+            // Any reproducible name ending with ".dex" should do but lets keep the same name
+            // as DexPathList.optimizedPathFor
+
+            File optimizedDirectory = path.getParentFile();
+            String fileName = path.getName();
+            String optimizedFileName =
+                    fileName.substring(0, fileName.length() - EXTRACTED_SUFFIX_LENGTH)
+                    + MultiDexExtractor.DEX_SUFFIX;
+            File result = new File(optimizedDirectory, optimizedFileName);
+            return result.getPath();
+        }
+    }
+
+    /**
+     * Installer for platform versions 4 to 13.
+     */
+    private static final class V4 {
+        static void install(ClassLoader loader,
+                List<? extends File> additionalClassPathEntries)
+                        throws IllegalArgumentException, IllegalAccessException,
+                        NoSuchFieldException, IOException {
+            /* The patched class loader is expected to be a descendant of
+             * dalvik.system.DexClassLoader. We modify its
+             * fields mPaths, mFiles, mZips and mDexs to append additional DEX
+             * file entries.
+             */
+            int extraSize = additionalClassPathEntries.size();
+
+            Field pathField = findField(loader, "path");
+
+            StringBuilder path = new StringBuilder((String) pathField.get(loader));
+            String[] extraPaths = new String[extraSize];
+            File[] extraFiles = new File[extraSize];
+            ZipFile[] extraZips = new ZipFile[extraSize];
+            DexFile[] extraDexs = new DexFile[extraSize];
+            for (ListIterator<? extends File> iterator = additionalClassPathEntries.listIterator();
+                    iterator.hasNext();) {
+                File additionalEntry = iterator.next();
+                String entryPath = additionalEntry.getAbsolutePath();
+                path.append(':').append(entryPath);
+                int index = iterator.previousIndex();
+                extraPaths[index] = entryPath;
+                extraFiles[index] = additionalEntry;
+                extraZips[index] = new ZipFile(additionalEntry);
+                extraDexs[index] = DexFile.loadDex(entryPath, entryPath + ".dex", 0);
+            }
+
+            pathField.set(loader, path.toString());
+            expandFieldArray(loader, "mPaths", extraPaths);
+            expandFieldArray(loader, "mFiles", extraFiles);
+            expandFieldArray(loader, "mZips", extraZips);
+            expandFieldArray(loader, "mDexs", extraDexs);
+        }
+    }
+
+}
diff --git a/androidx/multidex/MultiDexApplication.java b/androidx/multidex/MultiDexApplication.java
new file mode 100644
index 0000000..4c759e3
--- /dev/null
+++ b/androidx/multidex/MultiDexApplication.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2014 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 androidx.multidex;
+
+import android.app.Application;
+import android.content.Context;
+
+/**
+ * Minimal MultiDex capable application. To use the legacy multidex library there is 3 possibility:
+ * <ul>
+ * <li>Declare this class as the application in your AndroidManifest.xml.</li>
+ * <li>Have your {@link Application} extends this class.</li>
+ * <li>Have your {@link Application} override attachBaseContext starting with<br>
+ * <code>
+  protected void attachBaseContext(Context base) {<br>
+    super.attachBaseContext(base);<br>
+    MultiDex.install(this);
+    </code></li>
+ *   <ul>
+ */
+public class MultiDexApplication extends Application {
+  @Override
+  protected void attachBaseContext(Context base) {
+    super.attachBaseContext(base);
+    MultiDex.install(this);
+  }
+}
diff --git a/androidx/multidex/MultiDexExtractor.java b/androidx/multidex/MultiDexExtractor.java
new file mode 100644
index 0000000..a63d724
--- /dev/null
+++ b/androidx/multidex/MultiDexExtractor.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright (C) 2013 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 androidx.multidex;
+
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Build;
+import android.util.Log;
+
+import java.io.BufferedOutputStream;
+import java.io.Closeable;
+import java.io.File;
+import java.io.FileFilter;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.RandomAccessFile;
+import java.nio.channels.FileChannel;
+import java.nio.channels.FileLock;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * Exposes application secondary dex files as files in the application data
+ * directory.
+ * {@link MultiDexExtractor} is taking the file lock in the dex dir on creation and release it
+ * during close.
+ */
+final class MultiDexExtractor implements Closeable {
+
+    /**
+     * Zip file containing one secondary dex file.
+     */
+    private static class ExtractedDex extends File {
+        public long crc = NO_VALUE;
+
+        public ExtractedDex(File dexDir, String fileName) {
+            super(dexDir, fileName);
+        }
+    }
+
+    private static final String TAG = MultiDex.TAG;
+
+    /**
+     * We look for additional dex files named {@code classes2.dex},
+     * {@code classes3.dex}, etc.
+     */
+    private static final String DEX_PREFIX = "classes";
+    static final String DEX_SUFFIX = ".dex";
+
+    private static final String EXTRACTED_NAME_EXT = ".classes";
+    static final String EXTRACTED_SUFFIX = ".zip";
+    private static final int MAX_EXTRACT_ATTEMPTS = 3;
+
+    private static final String PREFS_FILE = "multidex.version";
+    private static final String KEY_TIME_STAMP = "timestamp";
+    private static final String KEY_CRC = "crc";
+    private static final String KEY_DEX_NUMBER = "dex.number";
+    private static final String KEY_DEX_CRC = "dex.crc.";
+    private static final String KEY_DEX_TIME = "dex.time.";
+
+    /**
+     * Size of reading buffers.
+     */
+    private static final int BUFFER_SIZE = 0x4000;
+    /* Keep value away from 0 because it is a too probable time stamp value */
+    private static final long NO_VALUE = -1L;
+
+    private static final String LOCK_FILENAME = "MultiDex.lock";
+    private final File sourceApk;
+    private final long sourceCrc;
+    private final File dexDir;
+    private final RandomAccessFile lockRaf;
+    private final FileChannel lockChannel;
+    private final FileLock cacheLock;
+
+    MultiDexExtractor(File sourceApk, File dexDir) throws IOException {
+        Log.i(TAG, "MultiDexExtractor(" + sourceApk.getPath() + ", " + dexDir.getPath() + ")");
+        this.sourceApk = sourceApk;
+        this.dexDir = dexDir;
+        sourceCrc = getZipCrc(sourceApk);
+        File lockFile = new File(dexDir, LOCK_FILENAME);
+        lockRaf = new RandomAccessFile(lockFile, "rw");
+        try {
+            lockChannel = lockRaf.getChannel();
+            try {
+                Log.i(TAG, "Blocking on lock " + lockFile.getPath());
+                cacheLock = lockChannel.lock();
+            } catch (IOException | RuntimeException | Error e) {
+                closeQuietly(lockChannel);
+                throw e;
+            }
+            Log.i(TAG, lockFile.getPath() + " locked");
+        } catch (IOException | RuntimeException | Error e) {
+            closeQuietly(lockRaf);
+            throw e;
+        }
+    }
+
+    /**
+     * Extracts application secondary dexes into files in the application data
+     * directory.
+     *
+     * @return a list of files that were created. The list may be empty if there
+     *         are no secondary dex files. Never return null.
+     * @throws IOException if encounters a problem while reading or writing
+     *         secondary dex files
+     */
+    List<? extends File> load(Context context, String prefsKeyPrefix, boolean forceReload)
+            throws IOException {
+        Log.i(TAG, "MultiDexExtractor.load(" + sourceApk.getPath() + ", " + forceReload + ", " +
+                prefsKeyPrefix + ")");
+
+        if (!cacheLock.isValid()) {
+            throw new IllegalStateException("MultiDexExtractor was closed");
+        }
+
+        List<ExtractedDex> files;
+        if (!forceReload && !isModified(context, sourceApk, sourceCrc, prefsKeyPrefix)) {
+            try {
+                files = loadExistingExtractions(context, prefsKeyPrefix);
+            } catch (IOException ioe) {
+                Log.w(TAG, "Failed to reload existing extracted secondary dex files,"
+                        + " falling back to fresh extraction", ioe);
+                files = performExtractions();
+                putStoredApkInfo(context, prefsKeyPrefix, getTimeStamp(sourceApk), sourceCrc,
+                        files);
+            }
+        } else {
+            if (forceReload) {
+                Log.i(TAG, "Forced extraction must be performed.");
+            } else {
+                Log.i(TAG, "Detected that extraction must be performed.");
+            }
+            files = performExtractions();
+            putStoredApkInfo(context, prefsKeyPrefix, getTimeStamp(sourceApk), sourceCrc,
+                    files);
+        }
+
+        Log.i(TAG, "load found " + files.size() + " secondary dex files");
+        return files;
+    }
+
+    @Override
+    public void close() throws IOException {
+        cacheLock.release();
+        lockChannel.close();
+        lockRaf.close();
+    }
+
+    /**
+     * Load previously extracted secondary dex files. Should be called only while owning the lock on
+     * {@link #LOCK_FILENAME}.
+     */
+    private List<ExtractedDex> loadExistingExtractions(
+            Context context,
+            String prefsKeyPrefix)
+            throws IOException {
+        Log.i(TAG, "loading existing secondary dex files");
+
+        final String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;
+        SharedPreferences multiDexPreferences = getMultiDexPreferences(context);
+        int totalDexNumber = multiDexPreferences.getInt(prefsKeyPrefix + KEY_DEX_NUMBER, 0);
+        if (totalDexNumber < 1) {
+            // Guard against SharedPreferences corruption
+            throw new IOException("Invalid dex number: " + totalDexNumber);
+        }
+        final List<ExtractedDex> files = new ArrayList<ExtractedDex>(totalDexNumber - 1);
+
+        for (int secondaryNumber = 2; secondaryNumber <= totalDexNumber; secondaryNumber++) {
+            String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;
+            ExtractedDex extractedFile = new ExtractedDex(dexDir, fileName);
+            if (extractedFile.isFile()) {
+                extractedFile.crc = getZipCrc(extractedFile);
+                long expectedCrc = multiDexPreferences.getLong(
+                        prefsKeyPrefix + KEY_DEX_CRC + secondaryNumber, NO_VALUE);
+                long expectedModTime = multiDexPreferences.getLong(
+                        prefsKeyPrefix + KEY_DEX_TIME + secondaryNumber, NO_VALUE);
+                long lastModified = extractedFile.lastModified();
+                if ((expectedModTime != lastModified)
+                        || (expectedCrc != extractedFile.crc)) {
+                    throw new IOException("Invalid extracted dex: " + extractedFile +
+                            " (key \"" + prefsKeyPrefix + "\"), expected modification time: "
+                            + expectedModTime + ", modification time: "
+                            + lastModified + ", expected crc: "
+                            + expectedCrc + ", file crc: " + extractedFile.crc);
+                }
+                files.add(extractedFile);
+            } else {
+                throw new IOException("Missing extracted secondary dex file '" +
+                        extractedFile.getPath() + "'");
+            }
+        }
+
+        return files;
+    }
+
+
+    /**
+     * Compare current archive and crc with values stored in {@link SharedPreferences}. Should be
+     * called only while owning the lock on {@link #LOCK_FILENAME}.
+     */
+    private static boolean isModified(Context context, File archive, long currentCrc,
+            String prefsKeyPrefix) {
+        SharedPreferences prefs = getMultiDexPreferences(context);
+        return (prefs.getLong(prefsKeyPrefix + KEY_TIME_STAMP, NO_VALUE) != getTimeStamp(archive))
+                || (prefs.getLong(prefsKeyPrefix + KEY_CRC, NO_VALUE) != currentCrc);
+    }
+
+    private static long getTimeStamp(File archive) {
+        long timeStamp = archive.lastModified();
+        if (timeStamp == NO_VALUE) {
+            // never return NO_VALUE
+            timeStamp--;
+        }
+        return timeStamp;
+    }
+
+
+    private static long getZipCrc(File archive) throws IOException {
+        long computedValue = ZipUtil.getZipCrc(archive);
+        if (computedValue == NO_VALUE) {
+            // never return NO_VALUE
+            computedValue--;
+        }
+        return computedValue;
+    }
+
+    private List<ExtractedDex> performExtractions() throws IOException {
+
+        final String extractedFilePrefix = sourceApk.getName() + EXTRACTED_NAME_EXT;
+
+        // It is safe to fully clear the dex dir because we own the file lock so no other process is
+        // extracting or running optimizing dexopt. It may cause crash of already running
+        // applications if for whatever reason we end up extracting again over a valid extraction.
+        clearDexDir();
+
+        List<ExtractedDex> files = new ArrayList<ExtractedDex>();
+
+        final ZipFile apk = new ZipFile(sourceApk);
+        try {
+
+            int secondaryNumber = 2;
+
+            ZipEntry dexFile = apk.getEntry(DEX_PREFIX + secondaryNumber + DEX_SUFFIX);
+            while (dexFile != null) {
+                String fileName = extractedFilePrefix + secondaryNumber + EXTRACTED_SUFFIX;
+                ExtractedDex extractedFile = new ExtractedDex(dexDir, fileName);
+                files.add(extractedFile);
+
+                Log.i(TAG, "Extraction is needed for file " + extractedFile);
+                int numAttempts = 0;
+                boolean isExtractionSuccessful = false;
+                while (numAttempts < MAX_EXTRACT_ATTEMPTS && !isExtractionSuccessful) {
+                    numAttempts++;
+
+                    // Create a zip file (extractedFile) containing only the secondary dex file
+                    // (dexFile) from the apk.
+                    extract(apk, dexFile, extractedFile, extractedFilePrefix);
+
+                    // Read zip crc of extracted dex
+                    try {
+                        extractedFile.crc = getZipCrc(extractedFile);
+                        isExtractionSuccessful = true;
+                    } catch (IOException e) {
+                        isExtractionSuccessful = false;
+                        Log.w(TAG, "Failed to read crc from " + extractedFile.getAbsolutePath(), e);
+                    }
+
+                    // Log size and crc of the extracted zip file
+                    Log.i(TAG, "Extraction " + (isExtractionSuccessful ? "succeeded" : "failed")
+                            + " '" + extractedFile.getAbsolutePath() + "': length "
+                            + extractedFile.length() + " - crc: " + extractedFile.crc);
+                    if (!isExtractionSuccessful) {
+                        // Delete the extracted file
+                        extractedFile.delete();
+                        if (extractedFile.exists()) {
+                            Log.w(TAG, "Failed to delete corrupted secondary dex '" +
+                                    extractedFile.getPath() + "'");
+                        }
+                    }
+                }
+                if (!isExtractionSuccessful) {
+                    throw new IOException("Could not create zip file " +
+                            extractedFile.getAbsolutePath() + " for secondary dex (" +
+                            secondaryNumber + ")");
+                }
+                secondaryNumber++;
+                dexFile = apk.getEntry(DEX_PREFIX + secondaryNumber + DEX_SUFFIX);
+            }
+        } finally {
+            try {
+                apk.close();
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to close resource", e);
+            }
+        }
+
+        return files;
+    }
+
+    /**
+     * Save {@link SharedPreferences}. Should be called only while owning the lock on
+     * {@link #LOCK_FILENAME}.
+     */
+    private static void putStoredApkInfo(Context context, String keyPrefix, long timeStamp,
+            long crc, List<ExtractedDex> extractedDexes) {
+        SharedPreferences prefs = getMultiDexPreferences(context);
+        SharedPreferences.Editor edit = prefs.edit();
+        edit.putLong(keyPrefix + KEY_TIME_STAMP, timeStamp);
+        edit.putLong(keyPrefix + KEY_CRC, crc);
+        edit.putInt(keyPrefix + KEY_DEX_NUMBER, extractedDexes.size() + 1);
+
+        int extractedDexId = 2;
+        for (ExtractedDex dex : extractedDexes) {
+            edit.putLong(keyPrefix + KEY_DEX_CRC + extractedDexId, dex.crc);
+            edit.putLong(keyPrefix + KEY_DEX_TIME + extractedDexId, dex.lastModified());
+            extractedDexId++;
+        }
+        /* Use commit() and not apply() as advised by the doc because we need synchronous writing of
+         * the editor content and apply is doing an "asynchronous commit to disk".
+         */
+        edit.commit();
+    }
+
+    /**
+     * Get the MuliDex {@link SharedPreferences} for the current application. Should be called only
+     * while owning the lock on {@link #LOCK_FILENAME}.
+     */
+    private static SharedPreferences getMultiDexPreferences(Context context) {
+        return context.getSharedPreferences(PREFS_FILE,
+                Build.VERSION.SDK_INT < 11 /* Build.VERSION_CODES.HONEYCOMB */
+                        ? Context.MODE_PRIVATE
+                        : Context.MODE_PRIVATE | 0x0004 /* Context.MODE_MULTI_PROCESS */);
+    }
+
+    /**
+     * Clear the dex dir from all files but the lock.
+     */
+    private void clearDexDir() {
+        File[] files = dexDir.listFiles(new FileFilter() {
+            @Override
+            public boolean accept(File pathname) {
+                return !pathname.getName().equals(LOCK_FILENAME);
+            }
+        });
+        if (files == null) {
+            Log.w(TAG, "Failed to list secondary dex dir content (" + dexDir.getPath() + ").");
+            return;
+        }
+        for (File oldFile : files) {
+            Log.i(TAG, "Trying to delete old file " + oldFile.getPath() + " of size " +
+                    oldFile.length());
+            if (!oldFile.delete()) {
+                Log.w(TAG, "Failed to delete old file " + oldFile.getPath());
+            } else {
+                Log.i(TAG, "Deleted old file " + oldFile.getPath());
+            }
+        }
+    }
+
+    private static void extract(ZipFile apk, ZipEntry dexFile, File extractTo,
+            String extractedFilePrefix) throws IOException, FileNotFoundException {
+
+        InputStream in = apk.getInputStream(dexFile);
+        ZipOutputStream out = null;
+        // Temp files must not start with extractedFilePrefix to get cleaned up in prepareDexDir()
+        File tmp = File.createTempFile("tmp-" + extractedFilePrefix, EXTRACTED_SUFFIX,
+                extractTo.getParentFile());
+        Log.i(TAG, "Extracting " + tmp.getPath());
+        try {
+            out = new ZipOutputStream(new BufferedOutputStream(new FileOutputStream(tmp)));
+            try {
+                ZipEntry classesDex = new ZipEntry("classes.dex");
+                // keep zip entry time since it is the criteria used by Dalvik
+                classesDex.setTime(dexFile.getTime());
+                out.putNextEntry(classesDex);
+
+                byte[] buffer = new byte[BUFFER_SIZE];
+                int length = in.read(buffer);
+                while (length != -1) {
+                    out.write(buffer, 0, length);
+                    length = in.read(buffer);
+                }
+                out.closeEntry();
+            } finally {
+                out.close();
+            }
+            if (!tmp.setReadOnly()) {
+                throw new IOException("Failed to mark readonly \"" + tmp.getAbsolutePath() +
+                        "\" (tmp of \"" + extractTo.getAbsolutePath() + "\")");
+            }
+            Log.i(TAG, "Renaming to " + extractTo.getPath());
+            if (!tmp.renameTo(extractTo)) {
+                throw new IOException("Failed to rename \"" + tmp.getAbsolutePath() +
+                        "\" to \"" + extractTo.getAbsolutePath() + "\"");
+            }
+        } finally {
+            closeQuietly(in);
+            tmp.delete(); // return status ignored
+        }
+    }
+
+    /**
+     * Closes the given {@code Closeable}. Suppresses any IO exceptions.
+     */
+    private static void closeQuietly(Closeable closeable) {
+        try {
+            closeable.close();
+        } catch (IOException e) {
+            Log.w(TAG, "Failed to close resource", e);
+        }
+    }
+}
diff --git a/androidx/multidex/MultiDexTest.java b/androidx/multidex/MultiDexTest.java
new file mode 100644
index 0000000..656b12a
--- /dev/null
+++ b/androidx/multidex/MultiDexTest.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2014 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 androidx.multidex;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test for {@link MultiDex} class.
+ */
+public class MultiDexTest {
+    @Test
+    public void testVersionCheck() {
+        Assert.assertFalse(MultiDex.isVMMultidexCapable(null));
+        Assert.assertFalse(MultiDex.isVMMultidexCapable("-1.32.54"));
+        Assert.assertFalse(MultiDex.isVMMultidexCapable("1.32.54"));
+        Assert.assertFalse(MultiDex.isVMMultidexCapable("1.32"));
+        Assert.assertFalse(MultiDex.isVMMultidexCapable("2.0"));
+        Assert.assertFalse(MultiDex.isVMMultidexCapable("2.000.1254"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("2.1.1254"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("2.1"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("2.2"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("2.1.0000"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("2.2.0000"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("002.0001.0010"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("3.0"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("3.0.0"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("3.0.1"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("3.1.0"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("03.1.132645"));
+        Assert.assertTrue(MultiDex.isVMMultidexCapable("03.2"));
+    }
+}
diff --git a/androidx/multidex/ZipEntryReader.java b/androidx/multidex/ZipEntryReader.java
new file mode 100644
index 0000000..a16e265
--- /dev/null
+++ b/androidx/multidex/ZipEntryReader.java
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+/* Apache Harmony HEADER because the code in this class comes mostly from ZipFile, ZipEntry and
+ * ZipConstants from android libcore.
+ */
+
+package androidx.multidex;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.charset.Charset;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+
+class ZipEntryReader {
+    static final Charset UTF_8 = Charset.forName("UTF-8");
+   /**
+     * General Purpose Bit Flags, Bit 0.
+     * If set, indicates that the file is encrypted.
+     */
+    private static final int GPBF_ENCRYPTED_FLAG = 1 << 0;
+
+    /**
+     * Supported General Purpose Bit Flags Mask.
+     * Bit mask of bits not supported.
+     * Note: The only bit that we will enforce at this time
+     * is the encrypted bit. Although other bits are not supported,
+     * we must not enforce them as this could break some legitimate
+     * use cases (See http://b/8617715).
+     */
+    private static final int GPBF_UNSUPPORTED_MASK = GPBF_ENCRYPTED_FLAG;
+    private static final long CENSIG = 0x2014b50;
+
+    static ZipEntry readEntry(ByteBuffer in) throws IOException {
+
+        int sig = in.getInt();
+        if (sig != CENSIG) {
+             throw new ZipException("Central Directory Entry not found");
+        }
+
+        in.position(8);
+        int gpbf = in.getShort() & 0xffff;
+
+        if ((gpbf & GPBF_UNSUPPORTED_MASK) != 0) {
+            throw new ZipException("Invalid General Purpose Bit Flag: " + gpbf);
+        }
+
+        int compressionMethod = in.getShort() & 0xffff;
+        int time = in.getShort() & 0xffff;
+        int modDate = in.getShort() & 0xffff;
+
+        // These are 32-bit values in the file, but 64-bit fields in this object.
+        long crc = ((long) in.getInt()) & 0xffffffffL;
+        long compressedSize = ((long) in.getInt()) & 0xffffffffL;
+        long size = ((long) in.getInt()) & 0xffffffffL;
+
+        int nameLength = in.getShort() & 0xffff;
+        int extraLength = in.getShort() & 0xffff;
+        int commentByteCount = in.getShort() & 0xffff;
+
+        // This is a 32-bit value in the file, but a 64-bit field in this object.
+        in.position(42);
+        long localHeaderRelOffset = ((long) in.getInt()) & 0xffffffffL;
+
+        byte[] nameBytes = new byte[nameLength];
+        in.get(nameBytes, 0, nameBytes.length);
+        String name = new String(nameBytes, 0, nameBytes.length, UTF_8);
+
+        ZipEntry entry = new ZipEntry(name);
+        entry.setMethod(compressionMethod);
+        entry.setTime(getTime(time, modDate));
+
+        entry.setCrc(crc);
+        entry.setCompressedSize(compressedSize);
+        entry.setSize(size);
+
+        // The RI has always assumed UTF-8. (If GPBF_UTF8_FLAG isn't set, the encoding is
+        // actually IBM-437.)
+        if (commentByteCount > 0) {
+            byte[] commentBytes = new byte[commentByteCount];
+            in.get(commentBytes, 0, commentByteCount);
+            entry.setComment(new String(commentBytes, 0, commentBytes.length, UTF_8));
+        }
+
+        if (extraLength > 0) {
+            byte[] extra = new byte[extraLength];
+            in.get(extra, 0, extraLength);
+            entry.setExtra(extra);
+        }
+
+        return entry;
+
+    }
+
+    private static long getTime(int time, int modDate) {
+        GregorianCalendar cal = new GregorianCalendar();
+        cal.set(Calendar.MILLISECOND, 0);
+        cal.set(1980 + ((modDate >> 9) & 0x7f), ((modDate >> 5) & 0xf) - 1,
+                modDate & 0x1f, (time >> 11) & 0x1f, (time >> 5) & 0x3f,
+                (time & 0x1f) << 1);
+        return cal.getTime().getTime();
+    }
+
+}
diff --git a/androidx/multidex/ZipUtil.java b/androidx/multidex/ZipUtil.java
new file mode 100644
index 0000000..fc33623
--- /dev/null
+++ b/androidx/multidex/ZipUtil.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You 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.
+ */
+/* Apache Harmony HEADER because the code in this class comes mostly from ZipFile, ZipEntry and
+ * ZipConstants from android libcore.
+ */
+
+package androidx.multidex;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.util.zip.CRC32;
+import java.util.zip.ZipException;
+
+/**
+ * Tools to build a quick partial crc of zip files.
+ */
+final class ZipUtil {
+    static class CentralDirectory {
+        long offset;
+        long size;
+    }
+
+    /* redefine those constant here because of bug 13721174 preventing to compile using the
+     * constants defined in ZipFile */
+    private static final int ENDHDR = 22;
+    private static final int ENDSIG = 0x6054b50;
+
+    /**
+     * Size of reading buffers.
+     */
+    private static final int BUFFER_SIZE = 0x4000;
+
+    /**
+     * Compute crc32 of the central directory of an apk. The central directory contains
+     * the crc32 of each entries in the zip so the computed result is considered valid for the whole
+     * zip file. Does not support zip64 nor multidisk but it should be OK for now since ZipFile does
+     * not either.
+     */
+    static long getZipCrc(File apk) throws IOException {
+        RandomAccessFile raf = new RandomAccessFile(apk, "r");
+        try {
+            CentralDirectory dir = findCentralDirectory(raf);
+
+            return computeCrcOfCentralDir(raf, dir);
+        } finally {
+            raf.close();
+        }
+    }
+
+    /* Package visible for testing */
+    static CentralDirectory findCentralDirectory(RandomAccessFile raf) throws IOException,
+            ZipException {
+        long scanOffset = raf.length() - ENDHDR;
+        if (scanOffset < 0) {
+            throw new ZipException("File too short to be a zip file: " + raf.length());
+        }
+
+        long stopOffset = scanOffset - 0x10000 /* ".ZIP file comment"'s max length */;
+        if (stopOffset < 0) {
+            stopOffset = 0;
+        }
+
+        int endSig = Integer.reverseBytes(ENDSIG);
+        while (true) {
+            raf.seek(scanOffset);
+            if (raf.readInt() == endSig) {
+                break;
+            }
+
+            scanOffset--;
+            if (scanOffset < stopOffset) {
+                throw new ZipException("End Of Central Directory signature not found");
+            }
+        }
+        // Read the End Of Central Directory. ENDHDR includes the signature
+        // bytes,
+        // which we've already read.
+
+        // Pull out the information we need.
+        raf.skipBytes(2); // diskNumber
+        raf.skipBytes(2); // diskWithCentralDir
+        raf.skipBytes(2); // numEntries
+        raf.skipBytes(2); // totalNumEntries
+        CentralDirectory dir = new CentralDirectory();
+        dir.size = Integer.reverseBytes(raf.readInt()) & 0xFFFFFFFFL;
+        dir.offset = Integer.reverseBytes(raf.readInt()) & 0xFFFFFFFFL;
+        return dir;
+    }
+
+    /* Package visible for testing */
+    static long computeCrcOfCentralDir(RandomAccessFile raf, CentralDirectory dir)
+            throws IOException {
+        CRC32 crc = new CRC32();
+        long stillToRead = dir.size;
+        raf.seek(dir.offset);
+        int length = (int) Math.min(BUFFER_SIZE, stillToRead);
+        byte[] buffer = new byte[BUFFER_SIZE];
+        length = raf.read(buffer, 0, length);
+        while (length != -1) {
+            crc.update(buffer, 0, length);
+            stillToRead -= length;
+            if (stillToRead == 0) {
+                break;
+            }
+            length = (int) Math.min(BUFFER_SIZE, stillToRead);
+            length = raf.read(buffer, 0, length);
+        }
+        return crc.getValue();
+    }
+}
diff --git a/androidx/multidex/ZipUtilTest.java b/androidx/multidex/ZipUtilTest.java
new file mode 100644
index 0000000..39a59ac
--- /dev/null
+++ b/androidx/multidex/ZipUtilTest.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright (C) 2014 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 androidx.multidex;
+
+import androidx.multidex.ZipUtil.CentralDirectory;
+
+import org.junit.Assert;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipException;
+import java.util.zip.ZipFile;
+
+/**
+ * Tests of ZipUtil class.
+ *
+ * The test assumes that ANDROID_BUILD_TOP environment variable is defined and point to the top of a
+ * built android tree. This is the case when the console used for running the tests is setup for
+ * android tree compilation.
+ */
+public class ZipUtilTest {
+    private static final File zipFile = new File(System.getenv("ANDROID_BUILD_TOP"),
+        "out/target/common/obj/JAVA_LIBRARIES/android-support-multidex_intermediates/javalib.jar");
+    @BeforeClass
+    public static void setupClass() throws ZipException, IOException {
+        // just verify the zip is valid
+        new ZipFile(zipFile).close();
+    }
+
+    @Test
+    public void testCrcDoNotCrash() throws IOException {
+
+        long crc =
+                ZipUtil.getZipCrc(zipFile);
+        System.out.println("crc is " + crc);
+
+    }
+
+    @Test
+    public void testCrcRange() throws IOException {
+        RandomAccessFile raf = new RandomAccessFile(zipFile, "r");
+        CentralDirectory dir = ZipUtil.findCentralDirectory(raf);
+        byte[] dirData = new byte[(int) dir.size];
+        int length = dirData.length;
+        int off = 0;
+        raf.seek(dir.offset);
+        while (length > 0) {
+            int read = raf.read(dirData, off, length);
+            if (length == -1) {
+                throw new EOFException();
+            }
+            length -= read;
+            off += read;
+        }
+        raf.close();
+        ByteBuffer buffer = ByteBuffer.wrap(dirData);
+        Map<String, ZipEntry> toCheck = new HashMap<String, ZipEntry>();
+        while (buffer.hasRemaining()) {
+            buffer = buffer.slice();
+            buffer.order(ByteOrder.LITTLE_ENDIAN);
+            ZipEntry entry = ZipEntryReader.readEntry(buffer);
+            toCheck.put(entry.getName(), entry);
+        }
+
+        ZipFile zip = new ZipFile(zipFile);
+        Assert.assertEquals(zip.size(), toCheck.size());
+        Enumeration<? extends ZipEntry> ref = zip.entries();
+        while (ref.hasMoreElements()) {
+            ZipEntry refEntry = ref.nextElement();
+            ZipEntry checkEntry = toCheck.get(refEntry.getName());
+            Assert.assertNotNull(checkEntry);
+            Assert.assertEquals(refEntry.getName(), checkEntry.getName());
+            Assert.assertEquals(refEntry.getComment(), checkEntry.getComment());
+            Assert.assertEquals(refEntry.getTime(), checkEntry.getTime());
+            Assert.assertEquals(refEntry.getCrc(), checkEntry.getCrc());
+            Assert.assertEquals(refEntry.getCompressedSize(), checkEntry.getCompressedSize());
+            Assert.assertEquals(refEntry.getSize(), checkEntry.getSize());
+            Assert.assertEquals(refEntry.getMethod(), checkEntry.getMethod());
+            Assert.assertArrayEquals(refEntry.getExtra(), checkEntry.getExtra());
+        }
+        zip.close();
+    }
+
+    @Test
+    public void testCrcValue() throws IOException {
+        ZipFile zip = new ZipFile(zipFile);
+        Enumeration<? extends ZipEntry> ref = zip.entries();
+        byte[] buffer = new byte[0x2000];
+        while (ref.hasMoreElements()) {
+            ZipEntry refEntry = ref.nextElement();
+            if (refEntry.getSize() > 0) {
+                File tmp = File.createTempFile("ZipUtilTest", ".fakezip");
+                InputStream in = zip.getInputStream(refEntry);
+                OutputStream out = new FileOutputStream(tmp);
+                int read = in.read(buffer);
+                while (read != -1) {
+                    out.write(buffer, 0, read);
+                    read = in.read(buffer);
+                }
+                in.close();
+                out.close();
+                RandomAccessFile raf = new RandomAccessFile(tmp, "r");
+                CentralDirectory dir = new CentralDirectory();
+                dir.offset = 0;
+                dir.size = raf.length();
+                long crc = ZipUtil.computeCrcOfCentralDir(raf, dir);
+                Assert.assertEquals(refEntry.getCrc(), crc);
+                raf.close();
+                tmp.delete();
+            }
+        }
+        zip.close();
+    }
+    @Test
+    public void testInvalidCrcValue() throws IOException {
+        ZipFile zip = new ZipFile(zipFile);
+        Enumeration<? extends ZipEntry> ref = zip.entries();
+        byte[] buffer = new byte[0x2000];
+        while (ref.hasMoreElements()) {
+            ZipEntry refEntry = ref.nextElement();
+            if (refEntry.getSize() > 0) {
+                File tmp = File.createTempFile("ZipUtilTest", ".fakezip");
+                InputStream in = zip.getInputStream(refEntry);
+                OutputStream out = new FileOutputStream(tmp);
+                int read = in.read(buffer);
+                while (read != -1) {
+                    out.write(buffer, 0, read);
+                    read = in.read(buffer);
+                }
+                in.close();
+                out.close();
+                RandomAccessFile raf = new RandomAccessFile(tmp, "r");
+                CentralDirectory dir = new CentralDirectory();
+                dir.offset = 0;
+                dir.size = raf.length() - 1;
+                long crc = ZipUtil.computeCrcOfCentralDir(raf, dir);
+                Assert.assertNotEquals(refEntry.getCrc(), crc);
+                raf.close();
+                tmp.delete();
+            }
+        }
+        zip.close();
+    }
+
+}
diff --git a/androidx/renderscript/Allocation.java b/androidx/renderscript/Allocation.java
new file mode 100644
index 0000000..b6588c0
--- /dev/null
+++ b/androidx/renderscript/Allocation.java
@@ -0,0 +1,3032 @@
+/*
+ * Copyright (C) 2008-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 androidx.renderscript;
+
+import java.nio.ByteBuffer;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.util.Log;
+import android.view.Surface;
+
+/**
+ * <p> This class provides the primary method through which data is passed to
+ * and from RenderScript kernels.  An Allocation provides the backing store for
+ * a given {@link androidx.renderscript.Type}.  </p>
+ *
+ * <p>An Allocation also contains a set of usage flags that denote how the
+ * Allocation could be used. For example, an Allocation may have usage flags
+ * specifying that it can be used from a script as well as input to a {@link
+ * androidx.renderscript.Sampler}. A developer must synchronize
+ * across these different usages using
+ * {@link androidx.renderscript.Allocation#syncAll} in
+ * order to ensure that different users of the Allocation have a consistent view
+ * of memory. For example, in the case where an Allocation is used as the output
+ * of one kernel and as Sampler input in a later kernel, a developer must call
+ * {@link #syncAll syncAll(Allocation.USAGE_SCRIPT)} prior to launching the
+ * second kernel to ensure correctness.
+ *
+ * <p>An Allocation can be populated with the {@link #copyFrom} routines. For
+ * more complex Element types, the {@link #copyFromUnchecked} methods can be
+ * used to copy from byte arrays or similar constructs.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating an application that uses
+ * RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
+ * developer guide.</p>
+ * </div>
+ **/
+public class Allocation extends BaseObj {
+    Type mType;
+    Bitmap mBitmap;
+    int mUsage;
+    int mSize;
+    Allocation mAdaptedAllocation;
+    ByteBuffer mByteBuffer = null;
+    long mByteBufferStride = 0;
+
+    boolean mConstrainedLOD;
+    boolean mConstrainedFace;
+    boolean mConstrainedY;
+    boolean mConstrainedZ;
+    boolean mReadAllowed = true;
+    boolean mWriteAllowed = true;
+    boolean mAutoPadding = false;
+    int mSelectedY;
+    int mSelectedZ;
+    int mSelectedLOD;
+    Type.CubemapFace mSelectedFace = Type.CubemapFace.POSITIVE_X;
+
+    int mCurrentDimX;
+    int mCurrentDimY;
+    int mCurrentDimZ;
+    int mCurrentCount;
+
+    private Element.DataType validateObjectIsPrimitiveArray(Object d, boolean checkType) {
+        final Class c = d.getClass();
+        if (!c.isArray()) {
+            throw new RSIllegalArgumentException("Object passed is not an array of primitives.");
+        }
+        final Class cmp = c.getComponentType();
+        if (!cmp.isPrimitive()) {
+            throw new RSIllegalArgumentException("Object passed is not an Array of primitives.");
+        }
+
+        if (cmp == Long.TYPE) {
+            if (checkType) {
+                validateIsInt64();
+                return mType.mElement.mType;
+            }
+            return Element.DataType.SIGNED_64;
+        }
+
+        if (cmp == Integer.TYPE) {
+            if (checkType) {
+                validateIsInt32();
+                return mType.mElement.mType;
+            }
+            return Element.DataType.SIGNED_32;
+        }
+
+        if (cmp == Short.TYPE) {
+            if (checkType) {
+                validateIsInt16();
+                return mType.mElement.mType;
+            }
+            return Element.DataType.SIGNED_16;
+        }
+
+        if (cmp == Byte.TYPE) {
+            if (checkType) {
+                validateIsInt8();
+                return mType.mElement.mType;
+            }
+            return Element.DataType.SIGNED_8;
+        }
+
+        if (cmp == Float.TYPE) {
+            if (checkType) {
+                validateIsFloat32();
+            }
+            return Element.DataType.FLOAT_32;
+        }
+
+        if (cmp == Double.TYPE) {
+            if (checkType) {
+                validateIsFloat64();
+            }
+            return Element.DataType.FLOAT_64;
+        }
+        return null;
+    }
+
+    /*
+     * Hold reference to the shared allocation in compat context
+     * for Incremental Support Lib.
+     */
+    long mIncCompatAllocation;
+    boolean mIncAllocDestroyed;
+    /**
+     * The usage of the Allocation.  These signal to RenderScript where to place
+     * the Allocation in memory.
+     *
+     */
+
+    /**
+     * The Allocation will be bound to and accessed by scripts.
+     */
+    public static final int USAGE_SCRIPT = 0x0001;
+
+    /**
+     * The Allocation will be used as a texture source by one or more graphics
+     * programs.
+     *
+     */
+    public static final int USAGE_GRAPHICS_TEXTURE = 0x0002;
+
+    /**
+     * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
+     * consumer.  This usage will cause the Allocation to be created as
+     * read-only.
+     *
+     */
+    public static final int USAGE_IO_INPUT = 0x0020;
+
+    /**
+     * The Allocation will be used as a {@link android.graphics.SurfaceTexture}
+     * producer.  The dimensions and format of the {@link
+     * android.graphics.SurfaceTexture} will be forced to those of the
+     * Allocation.
+     *
+     */
+    public static final int USAGE_IO_OUTPUT = 0x0040;
+
+    /**
+     * The Allocation's backing store will be inherited from another object
+     * (usually a {@link android.graphics.Bitmap}); copying to or from the
+     * original source Bitmap will cause a synchronization rather than a full
+     * copy.  {@link #syncAll} may also be used to synchronize the Allocation
+     * and the source Bitmap.
+     *
+     * <p>This is set by default for allocations created with {@link
+     * #createFromBitmap} in API version 18 and higher.</p>
+     *
+     */
+    public static final int USAGE_SHARED = 0x0080;
+
+    /**
+     * Controls mipmap behavior when using the bitmap creation and update
+     * functions.
+     */
+    public enum MipmapControl {
+        /**
+         * No mipmaps will be generated and the type generated from the incoming
+         * bitmap will not contain additional LODs.
+         */
+        MIPMAP_NONE(0),
+
+        /**
+         * A full mipmap chain will be created in script memory.  The Type of
+         * the Allocation will contain a full mipmap chain.  On upload, the full
+         * chain will be transferred.
+         */
+        MIPMAP_FULL(1),
+
+        /**
+         * The Type of the Allocation will be the same as MIPMAP_NONE.  It will
+         * not contain mipmaps.  On upload, the allocation data will contain a
+         * full mipmap chain generated from the top level in script memory.
+         */
+        MIPMAP_ON_SYNC_TO_TEXTURE(2);
+
+        int mID;
+        MipmapControl(int id) {
+            mID = id;
+        }
+    }
+
+    /**
+     * Getter & Setter for the dummy allocation for Inc Support Lib.
+     *
+     */
+    public long getIncAllocID() {
+        return mIncCompatAllocation;
+    }
+    public void setIncAllocID(long id) {
+        mIncCompatAllocation = id;
+    }
+
+    private long getIDSafe() {
+        if (mAdaptedAllocation != null) {
+            return mAdaptedAllocation.getID(mRS);
+        }
+        return getID(mRS);
+    }
+
+
+   /**
+     * Get the {@link androidx.renderscript.Element} of the {@link
+     * androidx.renderscript.Type} of the Allocation.
+     *
+     * @return Element
+     *
+     */
+    public Element getElement() {
+        return mType.getElement();
+    }
+
+    /**
+     * Get the usage flags of the Allocation.
+     *
+     * @return usage this Allocation's set of the USAGE_* flags OR'd together
+     *
+     */
+    public int getUsage() {
+        return mUsage;
+    }
+
+    /**
+     * Specifies the mapping between the Allocation's cells and an array's elements
+     * when data is copied from the Allocation to the array, or vice-versa.
+     *
+     * Only applies to an Allocation whose Element is a vector of length 3 (such as
+     * {@link Element#U8_3} or {@link Element#RGB_888}). Enabling this feature may make
+     * copying data from the Allocation to an array or vice-versa less efficient.
+     *
+     * <p> Vec3 Element cells are stored in an Allocation as Vec4 Element cells with
+     * the same {@link androidx.renderscript.Element.DataType}, with the fourth vector
+     * component treated as padding. When this feature is enabled, only the data components,
+     * i.e. the first 3 vector components of each cell, will be mapped between the array
+     * and the Allocation. When disabled, explicit mapping of the padding components
+     * is required, as described in the following example.
+     *
+     * <p> For example, when copying an integer array to an Allocation of two {@link
+     * Element#I32_3} cells using {@link #copyFrom(int[])}:
+     * <p> When disabled:
+     *     The array must have at least 8 integers, with the first 4 integers copied
+     *     to the first cell of the Allocation, and the next 4 integers copied to
+     *     the second cell. The 4th and 8th integers are mapped as the padding components.
+     *
+     * <p> When enabled:
+     *     The array just needs to have at least 6 integers, with the first 3 integers
+     *     copied to the the first cell as data components, and the next 3 copied to
+     *     the second cell. There is no mapping for the padding components.
+     *
+     * <p> Similarly, when copying a byte array to an Allocation of two {@link
+     * Element#I32_3} cells, using {@link #copyFromUnchecked(int[])}:
+     * <p> When disabled:
+     *     The array must have at least 32 bytes, with the first 16 bytes copied
+     *     to the first cell of the Allocation, and the next 16 bytes copied to
+     *     the second cell. The 13th-16th and 29th-32nd bytes are mapped as padding
+     *     components.
+     *
+     * <p> When enabled:
+     *     The array just needs to have at least 24 bytes, with the first 12 bytes copied
+     *     to the first cell of the Allocation, and the next 12 bytes copied to
+     *     the second cell. There is no mapping for the padding components.
+     *
+     * <p> Similar to copying data to an Allocation from an array, when copying data from an
+     * Allocation to an array, the padding components for Vec3 Element cells will not be
+     * copied/mapped to the array if AutoPadding is enabled.
+     *
+     * <p> Default: Disabled.
+     *
+     * @param useAutoPadding True: enable AutoPadding; False: disable AutoPadding
+     *
+     */
+    public void setAutoPadding(boolean useAutoPadding) {
+        mAutoPadding = useAutoPadding;
+    }
+
+    /**
+     * Get the size of the Allocation in bytes.
+     *
+     * @return size of the Allocation in bytes.
+     *
+     */
+    public int getBytesSize() {
+        if (mType.mDimYuv != 0) {
+            return (int)Math.ceil(mType.getCount() * mType.getElement().getBytesSize() * 1.5);
+        }
+        return mType.getCount() * mType.getElement().getBytesSize();
+    }
+
+    private void updateCacheInfo(Type t) {
+        mCurrentDimX = t.getX();
+        mCurrentDimY = t.getY();
+        mCurrentDimZ = t.getZ();
+        mCurrentCount = mCurrentDimX;
+        if (mCurrentDimY > 1) {
+            mCurrentCount *= mCurrentDimY;
+        }
+        if (mCurrentDimZ > 1) {
+            mCurrentCount *= mCurrentDimZ;
+        }
+    }
+
+    private void setBitmap(Bitmap b) {
+        mBitmap = b;
+    }
+
+    Allocation(long id, RenderScript rs, Type t, int usage) {
+        super(id, rs);
+        if ((usage & ~(USAGE_SCRIPT |
+                       USAGE_GRAPHICS_TEXTURE |
+                       USAGE_IO_INPUT |
+                       USAGE_IO_OUTPUT |
+                       USAGE_SHARED)) != 0) {
+            throw new RSIllegalArgumentException("Unknown usage specified.");
+        }
+
+        if ((usage & USAGE_IO_INPUT) != 0) {
+            mWriteAllowed = false;
+
+            if ((usage & ~(USAGE_IO_INPUT |
+                           USAGE_GRAPHICS_TEXTURE |
+                           USAGE_SCRIPT)) != 0) {
+                throw new RSIllegalArgumentException("Invalid usage combination.");
+            }
+        }
+
+        mType = t;
+        mUsage = usage;
+        mIncCompatAllocation = 0;
+        mIncAllocDestroyed = false;
+
+        if (t != null) {
+            // TODO: A3D doesn't have Type info during creation, so we can't
+            // calculate the size ahead of time. We can possibly add a method
+            // to update the size in the future if it seems reasonable.
+            mSize = mType.getCount() * mType.getElement().getBytesSize();
+            updateCacheInfo(t);
+        }
+        if (RenderScript.sUseGCHooks == true) {
+            try {
+                RenderScript.registerNativeAllocation.invoke(RenderScript.sRuntime, mSize);
+            } catch (Exception e) {
+                Log.e(RenderScript.LOG_TAG, "Couldn't invoke registerNativeAllocation:" + e);
+                throw new RSRuntimeException("Couldn't invoke registerNativeAllocation:" + e);
+            }
+        }
+    }
+
+    protected void finalize() throws Throwable {
+        if (RenderScript.sUseGCHooks == true) {
+            RenderScript.registerNativeFree.invoke(RenderScript.sRuntime, mSize);
+        }
+        super.finalize();
+    }
+
+    private void validateIsInt64() {
+        if ((mType.mElement.mType == Element.DataType.SIGNED_64) ||
+            (mType.mElement.mType == Element.DataType.UNSIGNED_64)) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "64 bit integer source does not match allocation type " + mType.mElement.mType);
+    }
+
+    private void validateIsInt32() {
+        if ((mType.mElement.mType == Element.DataType.SIGNED_32) ||
+            (mType.mElement.mType == Element.DataType.UNSIGNED_32)) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "32 bit integer source does not match allocation type " + mType.mElement.mType);
+    }
+
+    private void validateIsInt16() {
+        if ((mType.mElement.mType == Element.DataType.SIGNED_16) ||
+            (mType.mElement.mType == Element.DataType.UNSIGNED_16)) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "16 bit integer source does not match allocation type " + mType.mElement.mType);
+    }
+
+    private void validateIsInt8() {
+        if ((mType.mElement.mType == Element.DataType.SIGNED_8) ||
+            (mType.mElement.mType == Element.DataType.UNSIGNED_8)) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "8 bit integer source does not match allocation type " + mType.mElement.mType);
+    }
+
+    private void validateIsFloat32() {
+        if (mType.mElement.mType == Element.DataType.FLOAT_32) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "32 bit float source does not match allocation type " + mType.mElement.mType);
+    }
+
+    private void validateIsFloat64() {
+        if (mType.mElement.mType == Element.DataType.FLOAT_64) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "64 bit float source does not match allocation type " + mType.mElement.mType);
+    }
+
+    private void validateIsObject() {
+        if ((mType.mElement.mType == Element.DataType.RS_ELEMENT) ||
+            (mType.mElement.mType == Element.DataType.RS_TYPE) ||
+            (mType.mElement.mType == Element.DataType.RS_ALLOCATION) ||
+            (mType.mElement.mType == Element.DataType.RS_SAMPLER) ||
+            (mType.mElement.mType == Element.DataType.RS_SCRIPT)) {
+            return;
+        }
+        throw new RSIllegalArgumentException(
+            "Object source does not match allocation type " + mType.mElement.mType);
+    }
+
+    /**
+     * Get the {@link androidx.renderscript.Type} of the Allocation.
+     *
+     * @return Type
+     *
+     */
+    public Type getType() {
+        return mType;
+    }
+
+    /**
+     * Propagate changes from one usage of the Allocation to the
+     * other usages of the Allocation.
+     *
+     */
+    public void syncAll(int srcLocation) {
+        switch (srcLocation) {
+        case USAGE_SCRIPT:
+        case USAGE_GRAPHICS_TEXTURE:
+            break;
+        default:
+            throw new RSIllegalArgumentException("Source must be exactly one usage type.");
+        }
+        mRS.validate();
+        mRS.nAllocationSyncAll(getIDSafe(), srcLocation);
+    }
+
+    /**
+     * Send a buffer to the output stream.  The contents of the Allocation will
+     * be undefined after this operation. This operation is only valid if {@link
+     * #USAGE_IO_OUTPUT} is set on the Allocation.
+     *
+     *
+     */
+    public void ioSend() {
+        if ((mUsage & USAGE_IO_OUTPUT) == 0) {
+            throw new RSIllegalArgumentException(
+                "Can only send buffer if IO_OUTPUT usage specified.");
+        }
+        mRS.validate();
+        mRS.nAllocationIoSend(getID(mRS));
+    }
+
+    /**
+     * Delete once code is updated.
+     */
+    public void ioSendOutput() {
+        ioSend();
+    }
+    /**
+     * Gets or creates a ByteBuffer that contains the raw data of the current Allocation.
+     * <p> If the Allocation is created with USAGE_IO_INPUT, the returned ByteBuffer
+     * would contain the up-to-date data as READ ONLY.
+     * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
+     * the Allocation has certain alignment. The size of each row including padding,
+     * called stride, can be queried using the {@link #getStride()} method.
+     *
+     * Note: Operating on the ByteBuffer of a destroyed Allocation will triger errors.
+     *       The ByteBuffer will be Read-Only for devices before Lollopop (API 21).
+     *
+     * @return ByteBuffer The ByteBuffer associated with raw data pointer of the Allocation.
+     */
+    public ByteBuffer getByteBuffer() {
+        int xBytesSize = mType.getX() * mType.getElement().getBytesSize();
+        // When running on devices before L, we need to construct the ByteBuffer
+        // and explicitly copy the data from the allocation to it.
+        if (mRS.getDispatchAPILevel() < 21) {
+            byte[] data = null;
+            if (mType.getZ() > 0) {
+                // TODO: add support for 3D allocations.
+                return null;
+            } else if (mType.getY() > 0) {
+                // 2D Allocation
+                data = new byte[xBytesSize * mType.getY()];
+                copy2DRangeToUnchecked(0, 0, mType.getX(), mType.getY(), data,
+                                       Element.DataType.SIGNED_8, xBytesSize * mType.getY());
+            } else {
+                // 1D Allocation
+                data = new byte[xBytesSize];
+                copy1DRangeToUnchecked(0, mType.getX(), data);
+            }
+            ByteBuffer bBuffer = ByteBuffer.wrap(data).asReadOnlyBuffer();
+            mByteBufferStride = xBytesSize;
+            return bBuffer;
+        }
+        // Create a new ByteBuffer if it is not initialized or using IO_INPUT.
+        if (mByteBuffer == null || (mUsage & USAGE_IO_INPUT) != 0) {
+            mByteBuffer = mRS.nAllocationGetByteBuffer(getID(mRS), xBytesSize, mType.getY(), mType.getZ());
+        }
+        return mByteBuffer;
+    }
+
+    /**
+     * Gets the stride of the Allocation.
+     * For a 2D or 3D Allocation, the raw data maybe padded so that each row of
+     * the Allocation has certain alignment. The size of each row including such
+     * padding is called stride.
+     *
+     * @return the stride. For 1D Allocation, the stride will be the number of
+     *         bytes of this Allocation. For 2D and 3D Allocations, the stride
+     *         will be the stride in X dimension measuring in bytes.
+     */
+    public long getStride() {
+        if (mByteBufferStride ==0) {
+            if (mRS.getDispatchAPILevel() > 21) {
+                mByteBufferStride = mRS.nAllocationGetStride(getID(mRS));
+            } else {
+                mByteBufferStride = mType.getX() * mType.getElement().getBytesSize();
+            }
+        }
+        return mByteBufferStride;
+    }
+
+    /**
+     * Receive the latest input into the Allocation. This operation
+     * is only valid if {@link #USAGE_IO_INPUT} is set on the Allocation.
+     *
+     */
+    public void ioReceive() {
+        if ((mUsage & USAGE_IO_INPUT) == 0) {
+            throw new RSIllegalArgumentException(
+                "Can only receive if IO_INPUT usage specified.");
+        }
+        mRS.validate();
+        mRS.nAllocationIoReceive(getID(mRS));
+    }
+
+    /**
+     * Copy an array of RS objects to the Allocation.
+     *
+     * @param d Source array.
+     */
+    public void copyFrom(BaseObj[] d) {
+        mRS.validate();
+        validateIsObject();
+        if (d.length != mCurrentCount) {
+            throw new RSIllegalArgumentException("Array size mismatch, allocation sizeX = " +
+                                                 mCurrentCount + ", array length = " + d.length);
+        }
+
+        if (RenderScript.sPointerSize == 8) {
+            long i[] = new long[d.length * 4];
+            for (int ct=0; ct < d.length; ct++) {
+                i[ct * 4] = d[ct].getID(mRS);
+            }
+            copy1DRangeFromUnchecked(0, mCurrentCount, i);
+        } else {
+            int i[] = new int[d.length];
+            for (int ct=0; ct < d.length; ct++) {
+                i[ct] = (int)d[ct].getID(mRS);
+            }
+            copy1DRangeFromUnchecked(0, mCurrentCount, i);
+        }
+    }
+
+    private void validateBitmapFormat(Bitmap b) {
+        Bitmap.Config bc = b.getConfig();
+        if (bc == null) {
+            throw new RSIllegalArgumentException("Bitmap has an unsupported format for this operation");
+        }
+        switch (bc) {
+        case ALPHA_8:
+            if (mType.getElement().mKind != Element.DataKind.PIXEL_A) {
+                throw new RSIllegalArgumentException("Allocation kind is " +
+                                                     mType.getElement().mKind + ", type " +
+                                                     mType.getElement().mType +
+                                                     " of " + mType.getElement().getBytesSize() +
+                                                     " bytes, passed bitmap was " + bc);
+            }
+            break;
+        case ARGB_8888:
+            if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
+                (mType.getElement().getBytesSize() != 4)) {
+                throw new RSIllegalArgumentException("Allocation kind is " +
+                                                     mType.getElement().mKind + ", type " +
+                                                     mType.getElement().mType +
+                                                     " of " + mType.getElement().getBytesSize() +
+                                                     " bytes, passed bitmap was " + bc);
+            }
+            break;
+        case RGB_565:
+            if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGB) ||
+                (mType.getElement().getBytesSize() != 2)) {
+                throw new RSIllegalArgumentException("Allocation kind is " +
+                                                     mType.getElement().mKind + ", type " +
+                                                     mType.getElement().mType +
+                                                     " of " + mType.getElement().getBytesSize() +
+                                                     " bytes, passed bitmap was " + bc);
+            }
+            break;
+        case ARGB_4444:
+            if ((mType.getElement().mKind != Element.DataKind.PIXEL_RGBA) ||
+                (mType.getElement().getBytesSize() != 2)) {
+                throw new RSIllegalArgumentException("Allocation kind is " +
+                                                     mType.getElement().mKind + ", type " +
+                                                     mType.getElement().mType +
+                                                     " of " + mType.getElement().getBytesSize() +
+                                                     " bytes, passed bitmap was " + bc);
+            }
+            break;
+
+        }
+    }
+
+    private void validateBitmapSize(Bitmap b) {
+        if((mCurrentDimX != b.getWidth()) || (mCurrentDimY != b.getHeight())) {
+            throw new RSIllegalArgumentException("Cannot update allocation from bitmap, sizes mismatch");
+        }
+    }
+
+    private void copyFromUnchecked(Object array, Element.DataType dt, int arrayLen) {
+        mRS.validate();
+        if (mCurrentDimZ > 0) {
+            copy3DRangeFromUnchecked(0, 0, 0, mCurrentDimX, mCurrentDimY, mCurrentDimZ, array, dt, arrayLen);
+        } else if (mCurrentDimY > 0) {
+            copy2DRangeFromUnchecked(0, 0, mCurrentDimX, mCurrentDimY, array, dt, arrayLen);
+        } else {
+            copy1DRangeFromUnchecked(0, mCurrentCount, array, dt, arrayLen);
+        }
+    }
+
+    /**
+     * Copy into this Allocation from an array. This method does not guarantee
+     * that the Allocation is compatible with the input buffer; it copies memory
+     * without reinterpretation.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param array The source array
+     */
+    public void copyFromUnchecked(Object array) {
+        copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, false),
+                          java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy into this Allocation from an array. This method does not guarantee
+     * that the Allocation is compatible with the input buffer; it copies memory
+     * without reinterpretation.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d the source array
+     */
+    public void copyFromUnchecked(int[] d) {
+        copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
+    }
+
+    /**
+     * Copy into this Allocation from an array. This method does not guarantee
+     * that the Allocation is compatible with the input buffer; it copies memory
+     * without reinterpretation.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d the source array
+     */
+    public void copyFromUnchecked(short[] d) {
+        copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
+    }
+
+    /**
+     * Copy into this Allocation from an array. This method does not guarantee
+     * that the Allocation is compatible with the input buffer; it copies memory
+     * without reinterpretation.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d the source array
+     */
+    public void copyFromUnchecked(byte[] d) {
+        copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
+    }
+
+    /**
+     * Copy into this Allocation from an array. This method does not guarantee
+     * that the Allocation is compatible with the input buffer; it copies memory
+     * without reinterpretation.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d the source array
+     */
+    public void copyFromUnchecked(float[] d) {
+        copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
+    }
+
+
+    /**
+     * Copy into this Allocation from an array.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} does not match the array's
+     * primitive type.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param array The source array
+     */
+    public void copyFrom(Object array) {
+        copyFromUnchecked(array, validateObjectIsPrimitiveArray(array, true),
+                          java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy into this Allocation from an array.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d the source array
+     */
+    public void copyFrom(int[] d) {
+        validateIsInt32();
+        copyFromUnchecked(d, Element.DataType.SIGNED_32, d.length);
+    }
+
+    /**
+     * Copy into this Allocation from an array.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d the source array
+     */
+    public void copyFrom(short[] d) {
+        validateIsInt16();
+        copyFromUnchecked(d, Element.DataType.SIGNED_16, d.length);
+    }
+
+    /**
+     * Copy into this Allocation from an array.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d the source array
+     */
+    public void copyFrom(byte[] d) {
+        validateIsInt8();
+        copyFromUnchecked(d, Element.DataType.SIGNED_8, d.length);
+    }
+
+    /**
+     * Copy into this Allocation from an array.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+     * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d the source array
+     */
+    public void copyFrom(float[] d) {
+        validateIsFloat32();
+        copyFromUnchecked(d, Element.DataType.FLOAT_32, d.length);
+    }
+
+    /**
+     * Copy into an Allocation from a {@link android.graphics.Bitmap}.  The
+     * height, width, and format of the bitmap must match the existing
+     * allocation.
+     *
+     * <p>If the {@link android.graphics.Bitmap} is the same as the {@link
+     * android.graphics.Bitmap} used to create the Allocation with {@link
+     * #createFromBitmap} and {@link #USAGE_SHARED} is set on the Allocation,
+     * this will synchronize the Allocation with the latest data from the {@link
+     * android.graphics.Bitmap}, potentially avoiding the actual copy.</p>
+     *
+     * @param b the source bitmap
+     */
+    public void copyFrom(Bitmap b) {
+        mRS.validate();
+        if (b.getConfig() == null) {
+            Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
+            Canvas c = new Canvas(newBitmap);
+            c.drawBitmap(b, 0, 0, null);
+            copyFrom(newBitmap);
+            return;
+        }
+        validateBitmapSize(b);
+        validateBitmapFormat(b);
+        mRS.nAllocationCopyFromBitmap(getID(mRS), b);
+    }
+
+    /**
+     * Copy an Allocation from an Allocation.  The types of both allocations
+     * must be identical.
+     *
+     * @param a the source allocation
+     */
+    public void copyFrom(Allocation a) {
+        mRS.validate();
+        if (!mType.equals(a.getType())) {
+            throw new RSIllegalArgumentException("Types of allocations must match.");
+        }
+        copy2DRangeFrom(0, 0, mCurrentDimX, mCurrentDimY, a, 0, 0);
+    }
+
+
+    /**
+     * This is only intended to be used by auto-generated code reflected from
+     * the RenderScript script files and should not be used by developers.
+     *
+     * @param xoff
+     * @param fp
+     */
+    public void setFromFieldPacker(int xoff, FieldPacker fp) {
+        mRS.validate();
+        int eSize = mType.mElement.getBytesSize();
+        final byte[] data = fp.getData();
+        int data_length = fp.getPos();
+
+        int count = data_length / eSize;
+        if ((eSize * count) != data_length) {
+            throw new RSIllegalArgumentException("Field packer length " + data_length +
+                                               " not divisible by element size " + eSize + ".");
+        }
+        copy1DRangeFromUnchecked(xoff, count, data);
+    }
+
+    /**
+     * This is only intended to be used by auto-generated code reflected from
+     * the RenderScript script files.
+     *
+     * @param xoff
+     * @param component_number
+     * @param fp
+     */
+    public void setFromFieldPacker(int xoff, int component_number, FieldPacker fp) {
+        mRS.validate();
+        if (component_number >= mType.mElement.mElements.length) {
+            throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
+        }
+        if(xoff < 0) {
+            throw new RSIllegalArgumentException("Offset must be >= 0.");
+        }
+
+        final byte[] data = fp.getData();
+        int data_length = fp.getPos();
+        int eSize = mType.mElement.mElements[component_number].getBytesSize();
+        eSize *= mType.mElement.mArraySizes[component_number];
+
+        if (data_length != eSize) {
+            throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
+                                               " does not match component size " + eSize + ".");
+        }
+
+        mRS.nAllocationElementData1D(getIDSafe(), xoff, mSelectedLOD,
+                                     component_number, data, data_length);
+    }
+
+    /**
+     * @hide
+     * This is only intended to be used by auto-generated code reflected from
+     * the RenderScript script files.
+     *
+     * @param xoff
+     * @param yoff
+     * @param zoff
+     * @param component_number
+     * @param fp
+     */
+    /*
+    public void setFromFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
+        mRS.validate();
+        if (component_number >= mType.mElement.mElements.length) {
+            throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
+        }
+        if(xoff < 0) {
+            throw new RSIllegalArgumentException("Offset x must be >= 0.");
+        }
+        if(yoff < 0) {
+            throw new RSIllegalArgumentException("Offset y must be >= 0.");
+        }
+        if(zoff < 0) {
+            throw new RSIllegalArgumentException("Offset z must be >= 0.");
+        }
+
+        final byte[] data = fp.getData();
+        int data_length = fp.getPos();
+        int eSize = mType.mElement.mElements[component_number].getBytesSize();
+        eSize *= mType.mElement.mArraySizes[component_number];
+
+        if (data_length != eSize) {
+            throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
+                                               " does not match component size " + eSize + ".");
+        }
+
+        mRS.nAllocationElementData(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+                                   component_number, data, data_length);
+    }
+    */
+
+    private void data1DChecks(int off, int count, int len, int dataSize, boolean usePadding) {
+        mRS.validate();
+        if(off < 0) {
+            throw new RSIllegalArgumentException("Offset must be >= 0.");
+        }
+        if(count < 1) {
+            throw new RSIllegalArgumentException("Count must be >= 1.");
+        }
+        if((off + count) > mCurrentCount) {
+            throw new RSIllegalArgumentException("Overflow, Available count " + mCurrentCount +
+                                               ", got " + count + " at offset " + off + ".");
+        }
+        if(usePadding) {
+            if(len < dataSize / 4 * 3) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+        } else {
+            if(len < dataSize) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+        }
+    }
+
+    /**
+     * Generate a mipmap chain. This is only valid if the Type of the Allocation
+     * includes mipmaps.
+     *
+     * <p>This function will generate a complete set of mipmaps from the top
+     * level LOD and place them into the script memory space.</p>
+     *
+     * <p>If the Allocation is also using other memory spaces, a call to {@link
+     * #syncAll syncAll(Allocation.USAGE_SCRIPT)} is required.</p>
+     */
+    public void generateMipmaps() {
+        mRS.nAllocationGenerateMipmaps(getID(mRS));
+    }
+
+    private void copy1DRangeFromUnchecked(int off, int count, Object array,
+                                          Element.DataType dt, int arrayLen) {
+        final int dataSize = mType.mElement.getBytesSize() * count;
+        // AutoPadding for Vec3 Element
+        boolean usePadding = false;
+        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+            usePadding = true;
+        }
+        data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
+        mRS.nAllocationData1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
+                              mType.mElement.mType.mSize, usePadding);
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param array The source array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, Object array) {
+        copy1DRangeFromUnchecked(off, count, array,
+                                 validateObjectIsPrimitiveArray(array, false),
+                                 java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
+        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
+        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
+        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
+        copy1DRangeFromUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
+    }
+
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} does not match the component type
+     * of the array passed in.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param array The source array.
+     */
+    public void copy1DRangeFrom(int off, int count, Object array) {
+        copy1DRangeFromUnchecked(off, count, array,
+                                 validateObjectIsPrimitiveArray(array, true),
+                                 java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not an 32 bit integer nor a vector of 32 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeFrom(int off, int count, int[] d) {
+        validateIsInt32();
+        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not an 16 bit integer nor a vector of 16 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeFrom(int off, int count, short[] d) {
+        validateIsInt16();
+        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeFrom(int off, int count, byte[] d) {
+        validateIsInt8();
+        copy1DRangeFromUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
+    }
+
+    /**
+     * Copy an array into a 1D region of this Allocation.  This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+     * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array.
+     */
+    public void copy1DRangeFrom(int off, int count, float[] d) {
+        validateIsFloat32();
+        copy1DRangeFromUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
+    }
+
+     /**
+     * Copy part of an Allocation into this Allocation.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param data the source data allocation.
+     * @param dataOff off The offset of the first element in data to
+     *          be copied.
+     */
+    public void copy1DRangeFrom(int off, int count, Allocation data, int dataOff) {
+        mRS.nAllocationData2D(getIDSafe(), off, 0,
+                              mSelectedLOD, mSelectedFace.mID,
+                              count, 1, data.getID(mRS), dataOff, 0,
+                              data.mSelectedLOD, data.mSelectedFace.mID);
+    }
+
+    private void validate2DRange(int xoff, int yoff, int w, int h) {
+        if (mAdaptedAllocation != null) {
+
+        } else {
+
+            if (xoff < 0 || yoff < 0) {
+                throw new RSIllegalArgumentException("Offset cannot be negative.");
+            }
+            if (h < 0 || w < 0) {
+                throw new RSIllegalArgumentException("Height or width cannot be negative.");
+            }
+            if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY)) {
+                throw new RSIllegalArgumentException("Updated region larger than allocation.");
+            }
+        }
+    }
+
+    void copy2DRangeFromUnchecked(int xoff, int yoff, int w, int h, Object array,
+                                  Element.DataType dt, int arrayLen) {
+        mRS.validate();
+        validate2DRange(xoff, yoff, w, h);
+        final int dataSize = mType.mElement.getBytesSize() * w * h;
+        // AutoPadding for Vec3 Element
+        boolean usePadding = false;
+        int sizeBytes = arrayLen * dt.mSize;
+        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+            if (dataSize / 4 * 3 > sizeBytes) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+            usePadding = true;
+            sizeBytes = dataSize;
+        } else {
+            if (dataSize > sizeBytes) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+        }
+        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
+                              array, sizeBytes, dt,
+                              mType.mElement.mType.mSize, usePadding);
+    }
+
+    /**
+     * Copy from an array into a rectangular region in this Allocation.  The
+     * array is assumed to be tightly packed. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} does not match the input data type.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param w Width of the region to update
+     * @param h Height of the region to update
+     * @param array Data to be placed into the Allocation
+     */
+    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, Object array) {
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, array,
+                                 validateObjectIsPrimitiveArray(array, true),
+                                 java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy from an array into a rectangular region in this Allocation.  The
+     * array is assumed to be tightly packed. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not an 8 bit integer nor a vector of 8 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param w Width of the region to update
+     * @param h Height of the region to update
+     * @param data to be placed into the Allocation
+     */
+    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, byte[] data) {
+        validateIsInt8();
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+                                 Element.DataType.SIGNED_8, data.length);
+    }
+
+    /**
+     * Copy from an array into a rectangular region in this Allocation.  The
+     * array is assumed to be tightly packed. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param w Width of the region to update
+     * @param h Height of the region to update
+     * @param data to be placed into the Allocation
+     */
+    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, short[] data) {
+        validateIsInt16();
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+                                 Element.DataType.SIGNED_16, data.length);
+    }
+
+    /**
+     * Copy from an array into a rectangular region in this Allocation.  The
+     * array is assumed to be tightly packed. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param w Width of the region to update
+     * @param h Height of the region to update
+     * @param data to be placed into the Allocation
+     */
+    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, int[] data) {
+        validateIsInt32();
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+                                 Element.DataType.SIGNED_32, data.length);
+    }
+
+    /**
+     * Copy from an array into a rectangular region in this Allocation.  The
+     * array is assumed to be tightly packed. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+     * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param w Width of the region to update
+     * @param h Height of the region to update
+     * @param data to be placed into the Allocation
+     */
+    public void copy2DRangeFrom(int xoff, int yoff, int w, int h, float[] data) {
+        validateIsFloat32();
+        copy2DRangeFromUnchecked(xoff, yoff, w, h, data,
+                                 Element.DataType.FLOAT_32, data.length);
+    }
+
+    /**
+     * Copy a rectangular region from an Allocation into a rectangular region in
+     * this Allocation.
+     *
+     * @param xoff X offset of the region in this Allocation
+     * @param yoff Y offset of the region in this Allocation
+     * @param w Width of the region to update.
+     * @param h Height of the region to update.
+     * @param data source Allocation.
+     * @param dataXoff X offset in source Allocation
+     * @param dataYoff Y offset in source Allocation
+     */
+    public void copy2DRangeFrom(int xoff, int yoff, int w, int h,
+                                Allocation data, int dataXoff, int dataYoff) {
+        mRS.validate();
+        validate2DRange(xoff, yoff, w, h);
+        mRS.nAllocationData2D(getIDSafe(), xoff, yoff,
+                              mSelectedLOD, mSelectedFace.mID,
+                              w, h, data.getID(mRS), dataXoff, dataYoff,
+                              data.mSelectedLOD, data.mSelectedFace.mID);
+    }
+
+    /**
+     * Copy a {@link android.graphics.Bitmap} into an Allocation.  The height
+     * and width of the update will use the height and width of the {@link
+     * android.graphics.Bitmap}.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param data the Bitmap to be copied
+     */
+    public void copy2DRangeFrom(int xoff, int yoff, Bitmap data) {
+        mRS.validate();
+        if (data.getConfig() == null) {
+            Bitmap newBitmap = Bitmap.createBitmap(data.getWidth(), data.getHeight(), Bitmap.Config.ARGB_8888);
+            Canvas c = new Canvas(newBitmap);
+            c.drawBitmap(data, 0, 0, null);
+            copy2DRangeFrom(xoff, yoff, newBitmap);
+            return;
+        }
+        validateBitmapFormat(data);
+        validate2DRange(xoff, yoff, data.getWidth(), data.getHeight());
+        mRS.nAllocationData2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, data);
+    }
+
+    private void validate3DRange(int xoff, int yoff, int zoff, int w, int h, int d) {
+        if (mAdaptedAllocation != null) {
+
+        } else {
+
+            if (xoff < 0 || yoff < 0 || zoff < 0) {
+                throw new RSIllegalArgumentException("Offset cannot be negative.");
+            }
+            if (h < 0 || w < 0 || d < 0) {
+                throw new RSIllegalArgumentException("Height or width cannot be negative.");
+            }
+            if (((xoff + w) > mCurrentDimX) || ((yoff + h) > mCurrentDimY) || ((zoff + d) > mCurrentDimZ)) {
+                throw new RSIllegalArgumentException("Updated region larger than allocation.");
+            }
+        }
+    }
+
+    /**
+     * Copy a rectangular region from the array into the allocation.
+     * The array is assumed to be tightly packed.
+     *
+     * The data type of the array is not required to be the same as
+     * the element data type.
+     */
+    private void copy3DRangeFromUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
+                                          Object array, Element.DataType dt, int arrayLen) {
+        mRS.validate();
+        validate3DRange(xoff, yoff, zoff, w, h, d);
+        final int dataSize = mType.mElement.getBytesSize() * w * h * d;
+        // AutoPadding for Vec3 Element
+        boolean usePadding = false;
+        int sizeBytes = arrayLen * dt.mSize;
+        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+            if (dataSize / 4 * 3 > sizeBytes) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+            usePadding = true;
+            sizeBytes = dataSize;
+        } else {
+            if (dataSize > sizeBytes) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+        }
+        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
+                              array, sizeBytes, dt,
+                              mType.mElement.mType.mSize, usePadding);
+    }
+
+    /**
+     * Copy from an array into a 3D region in this Allocation.  The
+     * array is assumed to be tightly packed. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} does not match the input data type.
+     *
+     * <p> The size of the region is: w * h * d * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param zoff Z offset of the region to update in this Allocation
+     * @param w Width of the region to update
+     * @param h Height of the region to update
+     * @param d Depth of the region to update
+     * @param array to be placed into the allocation
+     */
+    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
+        copy3DRangeFromUnchecked(xoff, yoff, zoff, w, h, d, array,
+                                 validateObjectIsPrimitiveArray(array, true),
+                                 java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy a rectangular region into the allocation from another
+     * allocation.
+     *
+     * @param xoff X offset of the region to update in this Allocation
+     * @param yoff Y offset of the region to update in this Allocation
+     * @param zoff Z offset of the region to update in this Allocation
+     * @param w Width of the region to update.
+     * @param h Height of the region to update.
+     * @param d Depth of the region to update.
+     * @param data source allocation.
+     * @param dataXoff X offset of the region in the source Allocation
+     * @param dataYoff Y offset of the region in the source Allocation
+     * @param dataZoff Z offset of the region in the source Allocation
+     */
+    public void copy3DRangeFrom(int xoff, int yoff, int zoff, int w, int h, int d,
+                                Allocation data, int dataXoff, int dataYoff, int dataZoff) {
+        mRS.validate();
+        validate3DRange(xoff, yoff, zoff, w, h, d);
+        mRS.nAllocationData3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+                              w, h, d, data.getID(mRS), dataXoff, dataYoff, dataZoff,
+                              data.mSelectedLOD);
+    }
+
+
+    /**
+     * Copy from the Allocation into a {@link android.graphics.Bitmap}.  The
+     * bitmap must match the dimensions of the Allocation.
+     *
+     * @param b The bitmap to be set from the Allocation.
+     */
+    public void copyTo(Bitmap b) {
+        mRS.validate();
+        validateBitmapFormat(b);
+        validateBitmapSize(b);
+        mRS.nAllocationCopyToBitmap(getID(mRS), b);
+    }
+
+    private void copyTo(Object array, Element.DataType dt, int arrayLen) {
+        mRS.validate();
+        boolean usePadding = false;
+        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+            usePadding = true;
+        }
+        if (usePadding) {
+            if (dt.mSize * arrayLen < mSize / 4 * 3) {
+                throw new RSIllegalArgumentException(
+                    "Size of output array cannot be smaller than size of allocation.");
+            }
+        } else {
+            if (dt.mSize * arrayLen < mSize) {
+                throw new RSIllegalArgumentException(
+                    "Size of output array cannot be smaller than size of allocation.");
+            }
+        }
+        mRS.nAllocationRead(getID(mRS), array, dt, mType.mElement.mType.mSize, usePadding);
+    }
+
+    /**
+     * Copy from the Allocation into an array. The method is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} does not match the input data type.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells will be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param array The array to be set from the Allocation.
+     */
+    public void copyTo(Object array) {
+        copyTo(array, validateObjectIsPrimitiveArray(array, true),
+               java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy from the Allocation into a byte array. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells will be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d The array to be set from the Allocation.
+     */
+    public void copyTo(byte[] d) {
+        validateIsInt8();
+        copyTo(d, Element.DataType.SIGNED_8, d.length);
+    }
+
+    /**
+     * Copy from the Allocation into a short array. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not a 16 bit integer nor a vector of 16 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells will be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d The array to be set from the Allocation.
+     */
+    public void copyTo(short[] d) {
+        validateIsInt16();
+        copyTo(d, Element.DataType.SIGNED_16, d.length);
+    }
+
+    /**
+     * Copy from the Allocation into a int array. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is not a 32 bit integer nor a vector of 32 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells will be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d The array to be set from the Allocation.
+     */
+    public void copyTo(int[] d) {
+        validateIsInt32();
+        copyTo(d, Element.DataType.SIGNED_32, d.length);
+    }
+
+    /**
+     * Copy from the Allocation into a float array. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+     * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the Allocation {@link
+     * #getBytesSize getBytesSize()}.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells will be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the Allocation {@link #getBytesSize getBytesSize()}. The padding bytes for
+     * the cells must not be part of the array.
+     *
+     * @param d The array to be set from the Allocation.
+     */
+    public void copyTo(float[] d) {
+        validateIsFloat32();
+        copyTo(d, Element.DataType.FLOAT_32, d.length);
+    }
+
+    /**
+     * @hide
+     * This is only intended to be used by auto-generated code reflected from
+     * the RenderScript script files and should not be used by developers.
+     *
+     * @param xoff
+     * @param yoff
+     * @param zoff
+     * @param component_number
+     * @param fp
+     */
+    /*
+    public void copyToFieldPacker(int xoff, int yoff, int zoff, int component_number, FieldPacker fp) {
+        mRS.validate();
+        if (component_number >= mType.mElement.mElements.length) {
+            throw new RSIllegalArgumentException("Component_number " + component_number + " out of range.");
+        }
+        if(xoff < 0) {
+            throw new RSIllegalArgumentException("Offset x must be >= 0.");
+        }
+        if(yoff < 0) {
+            throw new RSIllegalArgumentException("Offset y must be >= 0.");
+        }
+        if(zoff < 0) {
+            throw new RSIllegalArgumentException("Offset z must be >= 0.");
+        }
+
+        final byte[] data = fp.getData();
+        int data_length = data.length;
+        int eSize = mType.mElement.mElements[component_number].getBytesSize();
+        eSize *= mType.mElement.mArraySizes[component_number];
+
+        if (data_length != eSize) {
+            throw new RSIllegalArgumentException("Field packer sizelength " + data_length +
+                                               " does not match component size " + eSize + ".");
+        }
+
+        mRS.nAllocationElementRead(getIDSafe(), xoff, yoff, zoff, mSelectedLOD,
+                                   component_number, data, data_length);
+    }
+    */
+
+    private void copy1DRangeToUnchecked(int off, int count, Object array,
+                                        Element.DataType dt, int arrayLen) {
+        final int dataSize = mType.mElement.getBytesSize() * count;
+        // AutoPadding for Vec3 Element
+        boolean usePadding = false;
+        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+            usePadding = true;
+        }
+        data1DChecks(off, count, arrayLen * dt.mSize, dataSize, usePadding);
+        mRS.nAllocationRead1D(getIDSafe(), off, mSelectedLOD, count, array, dataSize, dt,
+                              mType.mElement.mType.mSize, usePadding);
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param array The dest array
+     */
+    public void copy1DRangeToUnchecked(int off, int count, Object array) {
+        copy1DRangeToUnchecked(off, count, array,
+                               validateObjectIsPrimitiveArray(array, false),
+                               java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeToUnchecked(int off, int count, int[] d) {
+        copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_32, d.length);
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeToUnchecked(int off, int count, short[] d) {
+        copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_16, d.length);
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeToUnchecked(int off, int count, byte[] d) {
+        copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.SIGNED_8, d.length);
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array.  This method does not
+     * guarantee that the Allocation is compatible with the input buffer.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeToUnchecked(int off, int count, float[] d) {
+        copy1DRangeToUnchecked(off, count, (Object)d, Element.DataType.FLOAT_32, d.length);
+    }
+
+
+    /**
+     * Copy a 1D region of this Allocation into an array.  This method is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} does not match the component type
+     * of the array passed in.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param array The source array.
+     */
+    public void copy1DRangeTo(int off, int count, Object array) {
+        copy1DRangeToUnchecked(off, count, array,
+                               validateObjectIsPrimitiveArray(array, true),
+                               java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither a 32 bit integer nor a vector of 32 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeTo(int off, int count, int[] d) {
+        validateIsInt32();
+        copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_32, d.length);
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither a 16 bit integer nor a vector of 16 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeTo(int off, int count, short[] d) {
+        validateIsInt16();
+        copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_16, d.length);
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither an 8 bit integer nor a vector of 8 bit
+     * integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array
+     */
+    public void copy1DRangeTo(int off, int count, byte[] d) {
+        validateIsInt8();
+        copy1DRangeToUnchecked(off, count, d, Element.DataType.SIGNED_8, d.length);
+    }
+
+    /**
+     * Copy a 1D region of this Allocation into an array. This variant is type checked
+     * and will generate exceptions if the Allocation's {@link
+     * androidx.renderscript.Element} is neither a 32 bit float nor a vector of
+     * 32 bit floats {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: count * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param off The offset of the first element to be copied.
+     * @param count The number of elements to be copied.
+     * @param d the source array.
+     */
+    public void copy1DRangeTo(int off, int count, float[] d) {
+        validateIsFloat32();
+        copy1DRangeToUnchecked(off, count, d, Element.DataType.FLOAT_32, d.length);
+    }
+
+
+    void copy2DRangeToUnchecked(int xoff, int yoff, int w, int h, Object array,
+                                Element.DataType dt, int arrayLen) {
+        mRS.validate();
+        validate2DRange(xoff, yoff, w, h);
+        final int dataSize = mType.mElement.getBytesSize() * w * h;
+        // AutoPadding for Vec3 Element
+        boolean usePadding = false;
+        int sizeBytes = arrayLen * dt.mSize;
+        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+            if (dataSize / 4 * 3 > sizeBytes) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+            usePadding = true;
+            sizeBytes = dataSize;
+        } else {
+            if (dataSize > sizeBytes) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+        }
+        mRS.nAllocationRead2D(getIDSafe(), xoff, yoff, mSelectedLOD, mSelectedFace.mID, w, h,
+                              array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
+    }
+
+    /**
+     * Copy from a rectangular region in this Allocation into an array. This
+     * method is type checked and will generate exceptions if the Allocation's
+     * {@link androidx.renderscript.Element} does not match the component type
+     * of the array passed in.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to copy in this Allocation
+     * @param yoff Y offset of the region to copy in this Allocation
+     * @param w Width of the region to copy
+     * @param h Height of the region to copy
+     * @param array Dest Array to be copied into
+     */
+    public void copy2DRangeTo(int xoff, int yoff, int w, int h, Object array) {
+        copy2DRangeToUnchecked(xoff, yoff, w, h, array,
+                               validateObjectIsPrimitiveArray(array, true),
+                               java.lang.reflect.Array.getLength(array));
+    }
+
+    /**
+     * Copy from a rectangular region in this Allocation into an array. This
+     * variant is type checked and will generate exceptions if the Allocation's
+     * {@link androidx.renderscript.Element} is neither an 8 bit integer nor a vector
+     * of 8 bit integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to copy in this Allocation
+     * @param yoff Y offset of the region to copy in this Allocation
+     * @param w Width of the region to copy
+     * @param h Height of the region to copy
+     * @param data Dest Array to be copied into
+     */
+    public void copy2DRangeTo(int xoff, int yoff, int w, int h, byte[] data) {
+        validateIsInt8();
+        copy2DRangeToUnchecked(xoff, yoff, w, h, data,
+                               Element.DataType.SIGNED_8, data.length);
+    }
+
+    /**
+     * Copy from a rectangular region in this Allocation into an array. This
+     * variant is type checked and will generate exceptions if the Allocation's
+     * {@link androidx.renderscript.Element} is neither a 16 bit integer nor a vector
+     * of 16 bit integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to copy in this Allocation
+     * @param yoff Y offset of the region to copy in this Allocation
+     * @param w Width of the region to copy
+     * @param h Height of the region to copy
+     * @param data Dest Array to be copied into
+     */
+    public void copy2DRangeTo(int xoff, int yoff, int w, int h, short[] data) {
+        validateIsInt16();
+        copy2DRangeToUnchecked(xoff, yoff, w, h, data,
+                               Element.DataType.SIGNED_16, data.length);
+    }
+
+    /**
+     * Copy from a rectangular region in this Allocation into an array. This
+     * variant is type checked and will generate exceptions if the Allocation's
+     * {@link androidx.renderscript.Element} is neither a 32 bit integer nor a vector
+     * of 32 bit integers {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to copy in this Allocation
+     * @param yoff Y offset of the region to copy in this Allocation
+     * @param w Width of the region to copy
+     * @param h Height of the region to copy
+     * @param data Dest Array to be copied into
+     */
+    public void copy2DRangeTo(int xoff, int yoff, int w, int h, int[] data) {
+        validateIsInt32();
+        copy2DRangeToUnchecked(xoff, yoff, w, h, data,
+                               Element.DataType.SIGNED_32, data.length);
+    }
+
+    /**
+     * Copy from a rectangular region in this Allocation into an array. This
+     * variant is type checked and will generate exceptions if the Allocation's
+     * {@link androidx.renderscript.Element} is neither a 32 bit float nor a vector
+     * of 32 bit floats {@link androidx.renderscript.Element.DataType}.
+     *
+     * <p> The size of the region is: w * h * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to copy in this Allocation
+     * @param yoff Y offset of the region to copy in this Allocation
+     * @param w Width of the region to copy
+     * @param h Height of the region to copy
+     * @param data Dest Array to be copied into
+     */
+    public void copy2DRangeTo(int xoff, int yoff, int w, int h, float[] data) {
+        validateIsFloat32();
+        copy2DRangeToUnchecked(xoff, yoff, w, h, data,
+                               Element.DataType.FLOAT_32, data.length);
+    }
+
+
+    /**
+     * Copy from a 3D region in this Allocation into an array. This method does
+     * not guarantee that the Allocation is compatible with the input buffer.
+     * The array is assumed to be tightly packed.
+     *
+     * The data type of the array is not required to be the same as
+     * the element data type.
+     */
+    /*
+    private void copy3DRangeToUnchecked(int xoff, int yoff, int zoff, int w, int h, int d,
+                                        Object array, Element.DataType dt, int arrayLen) {
+        mRS.validate();
+        validate3DRange(xoff, yoff, zoff, w, h, d);
+        final int dataSize = mType.mElement.getBytesSize() * w * h * d;
+        // AutoPadding for Vec3 Element
+        boolean usePadding = false;
+        int sizeBytes = arrayLen * dt.mSize;
+        if (mAutoPadding && (mType.getElement().getVectorSize() == 3)) {
+            if (dataSize / 4 * 3 > sizeBytes) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+            usePadding = true;
+            sizeBytes = dataSize;
+        } else {
+            if (dataSize > sizeBytes) {
+                throw new RSIllegalArgumentException("Array too small for allocation type.");
+            }
+        }
+        mRS.nAllocationRead3D(getIDSafe(), xoff, yoff, zoff, mSelectedLOD, w, h, d,
+                              array, sizeBytes, dt, mType.mElement.mType.mSize, usePadding);
+    }
+    */
+
+    /**
+     * @hide
+     * Copy from a 3D region in this Allocation into an array. This
+     * method is type checked and will generate exceptions if the Allocation's
+     * {@link androidx.renderscript.Element} does not match the component type
+     * of the array passed in.
+     *
+     * <p> The size of the region is: w * h * d * {@link #getElement}.{@link
+     * Element#getBytesSize}.
+     *
+     * <p> If the Allocation does not have Vec3 Elements, then the size of the
+     * array in bytes must be at least the size of the region.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is disabled, then the size of the array in bytes must be at least the size
+     * of the region. The padding bytes for the cells must be part of the array.
+     *
+     * <p> If the Allocation has Vec3 Elements and {@link #setAutoPadding AutoPadding}
+     * is enabled, then the size of the array in bytes must be at least 3/4 the size
+     * of the region. The padding bytes for the cells must not be part of the array.
+     *
+     * @param xoff X offset of the region to copy in this Allocation
+     * @param yoff Y offset of the region to copy in this Allocation
+     * @param zoff Z offset of the region to copy in this Allocation
+     * @param w Width of the region to copy
+     * @param h Height of the region to copy
+     * @param d Depth of the region to copy
+     * @param array Dest Array to be copied into
+     */
+    /*
+    public void copy3DRangeTo(int xoff, int yoff, int zoff, int w, int h, int d, Object array) {
+        copy3DRangeToUnchecked(xoff, yoff, zoff, w, h, d, array,
+                                 validateObjectIsPrimitiveArray(array, true),
+                                 java.lang.reflect.Array.getLength(array));
+    }
+    */
+
+    // creation
+
+    static BitmapFactory.Options mBitmapOptions = new BitmapFactory.Options();
+    static {
+        mBitmapOptions.inScaled = false;
+    }
+
+    /**
+     * Creates a new Allocation with the given {@link
+     * androidx.renderscript.Type}, mipmap flag, and usage flags.
+     *
+     * @param type RenderScript type describing data layout
+     * @param mips specifies desired mipmap behaviour for the
+     *             allocation
+     * @param usage bit field specifying how the Allocation is
+     *              utilized
+     */
+    static public Allocation createTyped(RenderScript rs, Type type, MipmapControl mips, int usage) {
+        rs.validate();
+        if (type.getID(rs) == 0) {
+            throw new RSInvalidStateException("Bad Type");
+        }
+
+        if(!rs.usingIO() && (usage & (USAGE_IO_INPUT | USAGE_IO_INPUT)) != 0) {
+            throw new RSRuntimeException("USAGE_IO not supported, Allocation creation failed.");
+        }
+
+        long id = rs.nAllocationCreateTyped(type.getID(rs), mips.mID, usage, 0);
+        if (id == 0) {
+            throw new RSRuntimeException("Allocation creation failed.");
+        }
+        return new Allocation(id, rs, type, usage);
+    }
+
+    /**
+     * Creates an Allocation with the size specified by the type and no mipmaps
+     * generated by default
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param type renderscript type describing data layout
+     * @param usage bit field specifying how the allocation is
+     *              utilized
+     *
+     * @return allocation
+     */
+    static public Allocation createTyped(RenderScript rs, Type type, int usage) {
+        return createTyped(rs, type, MipmapControl.MIPMAP_NONE, usage);
+    }
+
+    /**
+     * Creates an Allocation for use by scripts with a given {@link
+     * androidx.renderscript.Type} and no mipmaps
+     *
+     * @param rs Context to which the Allocation will belong.
+     * @param type RenderScript Type describing data layout
+     *
+     * @return allocation
+     */
+    static public Allocation createTyped(RenderScript rs, Type type) {
+        return createTyped(rs, type, MipmapControl.MIPMAP_NONE, USAGE_SCRIPT);
+    }
+
+    /**
+     * Creates an Allocation with a specified number of given elements
+     *
+     * @param rs Context to which the Allocation will belong.
+     * @param e Element to use in the Allocation
+     * @param count the number of Elements in the Allocation
+     * @param usage bit field specifying how the Allocation is
+     *              utilized
+     *
+     * @return allocation
+     */
+    static public Allocation createSized(RenderScript rs, Element e,
+                                         int count, int usage) {
+        rs.validate();
+        Type.Builder b = new Type.Builder(rs, e);
+        b.setX(count);
+        Type t = b.create();
+
+        long id = rs.nAllocationCreateTyped(t.getID(rs), MipmapControl.MIPMAP_NONE.mID, usage, 0);
+        if (id == 0) {
+            throw new RSRuntimeException("Allocation creation failed.");
+        }
+        return new Allocation(id, rs, t, usage);
+    }
+
+    /**
+     * Creates an Allocation with a specified number of given elements
+     *
+     * @param rs Context to which the Allocation will belong.
+     * @param e Element to use in the Allocation
+     * @param count the number of Elements in the Allocation
+     *
+     * @return allocation
+     */
+    static public Allocation createSized(RenderScript rs, Element e, int count) {
+        return createSized(rs, e, count, USAGE_SCRIPT);
+    }
+
+    static Element elementFromBitmap(RenderScript rs, Bitmap b) {
+        final Bitmap.Config bc = b.getConfig();
+        if (bc == Bitmap.Config.ALPHA_8) {
+            return Element.A_8(rs);
+        }
+        if (bc == Bitmap.Config.ARGB_4444) {
+            return Element.RGBA_4444(rs);
+        }
+        if (bc == Bitmap.Config.ARGB_8888) {
+            return Element.RGBA_8888(rs);
+        }
+        if (bc == Bitmap.Config.RGB_565) {
+            return Element.RGB_565(rs);
+        }
+        throw new RSInvalidStateException("Bad bitmap type: " + bc);
+    }
+
+    static Type typeFromBitmap(RenderScript rs, Bitmap b,
+                                       MipmapControl mip) {
+        Element e = elementFromBitmap(rs, b);
+        Type.Builder tb = new Type.Builder(rs, e);
+        tb.setX(b.getWidth());
+        tb.setY(b.getHeight());
+        tb.setMipmaps(mip == MipmapControl.MIPMAP_FULL);
+        return tb.create();
+    }
+
+    /**
+     * Creates an Allocation from a {@link android.graphics.Bitmap}.
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param b Bitmap source for the allocation data
+     * @param mips specifies desired mipmap behaviour for the
+     *             allocation
+     * @param usage bit field specifying how the allocation is
+     *              utilized
+     *
+     * @return Allocation containing bitmap data
+     *
+     */
+    static public Allocation createFromBitmap(RenderScript rs, Bitmap b,
+                                              MipmapControl mips,
+                                              int usage) {
+        rs.validate();
+
+        // WAR undocumented color formats
+        if (b.getConfig() == null) {
+            if ((usage & USAGE_SHARED) != 0) {
+                throw new RSIllegalArgumentException("USAGE_SHARED cannot be used with a Bitmap that has a null config.");
+            }
+            Bitmap newBitmap = Bitmap.createBitmap(b.getWidth(), b.getHeight(), Bitmap.Config.ARGB_8888);
+            Canvas c = new Canvas(newBitmap);
+            c.drawBitmap(b, 0, 0, null);
+            return createFromBitmap(rs, newBitmap, mips, usage);
+        }
+
+        Type t = typeFromBitmap(rs, b, mips);
+
+        // enable optimized bitmap path only with no mipmap and script-only usage
+        if (mips == MipmapControl.MIPMAP_NONE &&
+            t.getElement().isCompatible(Element.RGBA_8888(rs)) &&
+            usage == (USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE)) {
+            long id = rs.nAllocationCreateBitmapBackedAllocation(t.getID(rs), mips.mID, b, usage);
+            if (id == 0) {
+                throw new RSRuntimeException("Load failed.");
+            }
+
+            // keep a reference to the Bitmap around to prevent GC
+            Allocation alloc = new Allocation(id, rs, t, usage);
+            alloc.setBitmap(b);
+            return alloc;
+        }
+
+
+        long id = rs.nAllocationCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
+        if (id == 0) {
+            throw new RSRuntimeException("Load failed.");
+        }
+        return new Allocation(id, rs, t, usage);
+    }
+
+    /**
+     * Associate a {@link android.view.Surface} with this Allocation. This
+     * operation is only valid for Allocations with {@link #USAGE_IO_OUTPUT}.
+     *
+     * @param sur Surface to associate with allocation
+     */
+    public void setSurface(Surface sur) {
+        mRS.validate();
+        if ((mUsage & USAGE_IO_OUTPUT) == 0) {
+            throw new RSInvalidStateException("Allocation is not USAGE_IO_OUTPUT.");
+        }
+
+        mRS.nAllocationSetSurface(getID(mRS), sur);
+    }
+
+    /**
+     * Creates an Allocation from a {@link android.graphics.Bitmap}.
+     *
+     * <p>This Allocation will be created with {@link #USAGE_SHARED}, and
+     * {@link #USAGE_SCRIPT}.</p>
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param b bitmap source for the allocation data
+     *
+     * @return Allocation containing bitmap data
+     *
+     */
+    static public Allocation createFromBitmap(RenderScript rs, Bitmap b) {
+        return createFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
+                                USAGE_SHARED | USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
+    }
+
+    /**
+     * Creates a cubemap Allocation from a {@link android.graphics.Bitmap}
+     * containing the horizontal list of cube faces. Each face must be a square,
+     * have the same size as all other faces, and have a width that is a power
+     * of 2.
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param b Bitmap with cubemap faces layed out in the following
+     *          format: right, left, top, bottom, front, back
+     * @param mips specifies desired mipmap behaviour for the cubemap
+     * @param usage bit field specifying how the cubemap is utilized
+     *
+     * @return allocation containing cubemap data
+     *
+     */
+    static public Allocation createCubemapFromBitmap(RenderScript rs, Bitmap b,
+                                                     MipmapControl mips,
+                                                     int usage) {
+        rs.validate();
+
+        int height = b.getHeight();
+        int width = b.getWidth();
+
+        if (width % 6 != 0) {
+            throw new RSIllegalArgumentException("Cubemap height must be multiple of 6");
+        }
+        if (width / 6 != height) {
+            throw new RSIllegalArgumentException("Only square cube map faces supported");
+        }
+        boolean isPow2 = (height & (height - 1)) == 0;
+        if (!isPow2) {
+            throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
+        }
+
+        Element e = elementFromBitmap(rs, b);
+        Type.Builder tb = new Type.Builder(rs, e);
+        tb.setX(height);
+        tb.setY(height);
+        tb.setFaces(true);
+        tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
+        Type t = tb.create();
+
+        long id = rs.nAllocationCubeCreateFromBitmap(t.getID(rs), mips.mID, b, usage);
+        if(id == 0) {
+            throw new RSRuntimeException("Load failed for bitmap " + b + " element " + e);
+        }
+        return new Allocation(id, rs, t, usage);
+    }
+
+    /**
+     * Creates a non-mipmapped cubemap Allocation for use as a graphics texture
+     * from a {@link android.graphics.Bitmap} containing the horizontal list of
+     * cube faces. Each face must be a square, have the same size as all other
+     * faces, and have a width that is a power of 2.
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param b bitmap with cubemap faces layed out in the following
+     *          format: right, left, top, bottom, front, back
+     *
+     * @return allocation containing cubemap data
+     *
+     */
+    static public Allocation createCubemapFromBitmap(RenderScript rs,
+                                                     Bitmap b) {
+        return createCubemapFromBitmap(rs, b, MipmapControl.MIPMAP_NONE,
+                                       USAGE_GRAPHICS_TEXTURE);
+    }
+
+    /**
+     * Creates a cubemap Allocation from 6 {@link android.graphics.Bitmap}
+     * objects containing the cube faces. Each face must be a square, have the
+     * same size as all other faces, and have a width that is a power of 2.
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param xpos cubemap face in the positive x direction
+     * @param xneg cubemap face in the negative x direction
+     * @param ypos cubemap face in the positive y direction
+     * @param yneg cubemap face in the negative y direction
+     * @param zpos cubemap face in the positive z direction
+     * @param zneg cubemap face in the negative z direction
+     * @param mips specifies desired mipmap behaviour for the cubemap
+     * @param usage bit field specifying how the cubemap is utilized
+     *
+     * @return allocation containing cubemap data
+     *
+     */
+    static public Allocation createCubemapFromCubeFaces(RenderScript rs,
+                                                        Bitmap xpos,
+                                                        Bitmap xneg,
+                                                        Bitmap ypos,
+                                                        Bitmap yneg,
+                                                        Bitmap zpos,
+                                                        Bitmap zneg,
+                                                        MipmapControl mips,
+                                                        int usage) {
+        /*
+        int height = xpos.getHeight();
+        if (xpos.getWidth() != height ||
+            xneg.getWidth() != height || xneg.getHeight() != height ||
+            ypos.getWidth() != height || ypos.getHeight() != height ||
+            yneg.getWidth() != height || yneg.getHeight() != height ||
+            zpos.getWidth() != height || zpos.getHeight() != height ||
+            zneg.getWidth() != height || zneg.getHeight() != height) {
+            throw new RSIllegalArgumentException("Only square cube map faces supported");
+        }
+        boolean isPow2 = (height & (height - 1)) == 0;
+        if (!isPow2) {
+            throw new RSIllegalArgumentException("Only power of 2 cube faces supported");
+        }
+
+        Element e = elementFromBitmap(rs, xpos);
+        Type.Builder tb = new Type.Builder(rs, e);
+        tb.setX(height);
+        tb.setY(height);
+        tb.setFaces(true);
+        tb.setMipmaps(mips == MipmapControl.MIPMAP_FULL);
+        Type t = tb.create();
+        Allocation cubemap = Allocation.createTyped(rs, t, mips, usage);
+
+        AllocationAdapter adapter = AllocationAdapter.create2D(rs, cubemap);
+        adapter.setFace(Type.CubemapFace.POSITIVE_X);
+        adapter.copyFrom(xpos);
+        adapter.setFace(Type.CubemapFace.NEGATIVE_X);
+        adapter.copyFrom(xneg);
+        adapter.setFace(Type.CubemapFace.POSITIVE_Y);
+        adapter.copyFrom(ypos);
+        adapter.setFace(Type.CubemapFace.NEGATIVE_Y);
+        adapter.copyFrom(yneg);
+        adapter.setFace(Type.CubemapFace.POSITIVE_Z);
+        adapter.copyFrom(zpos);
+        adapter.setFace(Type.CubemapFace.NEGATIVE_Z);
+        adapter.copyFrom(zneg);
+
+        return cubemap;
+        */
+        return null;
+    }
+
+    /**
+     * Creates a non-mipmapped cubemap Allocation for use as a sampler input
+     * from 6 {@link android.graphics.Bitmap} objects containing the cube
+     * faces. Each face must be a square, have the same size as all other faces,
+     * and have a width that is a power of 2.
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param xpos cubemap face in the positive x direction
+     * @param xneg cubemap face in the negative x direction
+     * @param ypos cubemap face in the positive y direction
+     * @param yneg cubemap face in the negative y direction
+     * @param zpos cubemap face in the positive z direction
+     * @param zneg cubemap face in the negative z direction
+     *
+     * @return allocation containing cubemap data
+     *
+     */
+    static public Allocation createCubemapFromCubeFaces(RenderScript rs,
+                                                        Bitmap xpos,
+                                                        Bitmap xneg,
+                                                        Bitmap ypos,
+                                                        Bitmap yneg,
+                                                        Bitmap zpos,
+                                                        Bitmap zneg) {
+        return createCubemapFromCubeFaces(rs, xpos, xneg, ypos, yneg,
+                                          zpos, zneg, MipmapControl.MIPMAP_NONE,
+                                          USAGE_GRAPHICS_TEXTURE);
+    }
+
+    /**
+     * Creates an Allocation from the Bitmap referenced
+     * by resource ID.
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param res application resources
+     * @param id resource id to load the data from
+     * @param mips specifies desired mipmap behaviour for the
+     *             allocation
+     * @param usage bit field specifying how the allocation is
+     *              utilized
+     *
+     * @return Allocation containing resource data
+     *
+     */
+    static public Allocation createFromBitmapResource(RenderScript rs,
+                                                      Resources res,
+                                                      int id,
+                                                      MipmapControl mips,
+                                                      int usage) {
+
+        rs.validate();
+        if ((usage & (USAGE_SHARED | USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
+            throw new RSIllegalArgumentException("Unsupported usage specified.");
+        }
+        Bitmap b = BitmapFactory.decodeResource(res, id);
+        Allocation alloc = createFromBitmap(rs, b, mips, usage);
+        b.recycle();
+        return alloc;
+    }
+
+    /**
+     * Creates a non-mipmapped Allocation to use as a graphics texture from the
+     * {@link android.graphics.Bitmap} referenced by resource ID.
+     *
+     * <p>This allocation will be created with {@link #USAGE_SCRIPT} and
+     * {@link #USAGE_GRAPHICS_TEXTURE}.</p>
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param res application resources
+     * @param id resource id to load the data from
+     *
+     * @return Allocation containing resource data
+     *
+     */
+    static public Allocation createFromBitmapResource(RenderScript rs,
+                                                      Resources res,
+                                                      int id) {
+        return createFromBitmapResource(rs, res, id,
+                                        MipmapControl.MIPMAP_NONE,
+                                        USAGE_SCRIPT | USAGE_GRAPHICS_TEXTURE);
+    }
+
+    /**
+     * Creates an Allocation containing string data encoded in UTF-8 format.
+     *
+     * @param rs Context to which the allocation will belong.
+     * @param str string to create the allocation from
+     * @param usage bit field specifying how the allocaiton is
+     *              utilized
+     *
+     */
+    static public Allocation createFromString(RenderScript rs,
+                                              String str,
+                                              int usage) {
+        rs.validate();
+        byte[] allocArray = null;
+        try {
+            allocArray = str.getBytes("UTF-8");
+            Allocation alloc = Allocation.createSized(rs, Element.U8(rs), allocArray.length, usage);
+            alloc.copyFrom(allocArray);
+            return alloc;
+        }
+        catch (Exception e) {
+            throw new RSRuntimeException("Could not convert string to utf-8.");
+        }
+    }
+
+    /**
+     * Frees any native resources associated with this object.  The
+     * primary use is to force immediate cleanup of resources when it is
+     * believed the GC will not respond quickly enough.
+     * For USAGE_IO_OUTPUT, destroy() implies setSurface(null).
+     */
+    @Override
+    public void destroy() {
+        if (mIncCompatAllocation != 0) {
+            boolean shouldDestroy = false;
+            synchronized(this) {
+                if (!mIncAllocDestroyed) {
+                    shouldDestroy = true;
+                    mIncAllocDestroyed = true;
+                }
+            }
+
+            if (shouldDestroy) {
+                // must include nObjDestroy in the critical section
+                ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
+                rlock.lock();
+                if(mRS.isAlive()) {
+                    mRS.nIncObjDestroy(mIncCompatAllocation);
+                }
+                rlock.unlock();
+                mIncCompatAllocation = 0;
+            }
+        }
+        if ((mUsage & (USAGE_IO_INPUT | USAGE_IO_OUTPUT)) != 0) {
+            setSurface(null);
+        }
+        super.destroy();
+    }
+
+}
diff --git a/androidx/renderscript/BaseObj.java b/androidx/renderscript/BaseObj.java
new file mode 100644
index 0000000..eda0066
--- /dev/null
+++ b/androidx/renderscript/BaseObj.java
@@ -0,0 +1,155 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.util.Log;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+/**
+ * BaseObj is the base class for all RenderScript objects owned by a RS context.
+ * It is responsible for lifetime management and resource tracking. This class
+ * should not be used by a user application.
+ *
+ **/
+public class BaseObj {
+    BaseObj(long id, RenderScript rs) {
+        rs.validate();
+        mRS = rs;
+        mID = id;
+        mDestroyed = false;
+    }
+
+    void setID(long id) {
+        if (mID != 0) {
+            throw new RSRuntimeException("Internal Error, reset of object ID.");
+        }
+        mID = id;
+    }
+
+    /**
+     * Lookup the native object ID for this object.  Primarily used by the
+     * generated reflected code.
+     *
+     * @param rs Context to verify against internal context for
+     *           match.
+     *
+     * @return long
+     */
+    long getID(RenderScript rs) {
+        mRS.validate();
+        if (mDestroyed) {
+            throw new RSInvalidStateException("using a destroyed object.");
+        }
+        if (mID == 0) {
+            throw new RSRuntimeException("Internal error: Object id 0.");
+        }
+        if ((rs != null) && (rs != mRS)) {
+            throw new RSInvalidStateException("using object with mismatched context.");
+        }
+        return mID;
+    }
+
+    android.renderscript.BaseObj getNObj() {
+        return null;
+    }
+
+    void checkValid() {
+        if ((mID == 0) && (getNObj() == null)) {
+            throw new RSIllegalArgumentException("Invalid object.");
+        }
+    }
+
+    private long mID;
+    private boolean mDestroyed;
+    RenderScript mRS;
+
+    private void helpDestroy() {
+        boolean shouldDestroy = false;
+        synchronized(this) {
+            if (!mDestroyed) {
+                shouldDestroy = true;
+                mDestroyed = true;
+            }
+        }
+
+        if (shouldDestroy) {
+            // must include nObjDestroy in the critical section
+            ReentrantReadWriteLock.ReadLock rlock = mRS.mRWLock.readLock();
+            rlock.lock();
+            if(mRS.isAlive()) {
+                mRS.nObjDestroy(mID);
+            }
+            rlock.unlock();
+            mRS = null;
+            mID = 0;
+        }
+    }
+
+
+    protected void finalize() throws Throwable {
+        helpDestroy();
+        super.finalize();
+    }
+
+    /**
+     * Frees any native resources associated with this object.  The
+     * primary use is to force immediate cleanup of resources when it is
+     * believed the GC will not respond quickly enough.
+     */
+    public void destroy() {
+        if(mDestroyed) {
+            throw new RSInvalidStateException("Object already destroyed.");
+        }
+        helpDestroy();
+    }
+
+    /**
+     * Calculates the hash code value for a BaseObj.
+     *
+     * @return int
+     */
+    @Override
+    public int hashCode() {
+        return (int)((mID & 0xfffffff) ^ (mID >> 32));
+    }
+
+    /**
+     * Compare the current BaseObj with another BaseObj for equality.
+     *
+     * @param obj The object to check equality with.
+     *
+     * @return boolean
+     */
+    @Override
+    public boolean equals(Object obj) {
+        // Early-out check to see if both BaseObjs are actually the same
+        if (this == obj)
+            return true;
+
+        if (obj == null) {
+            return false;
+        }
+
+        if (getClass() != obj.getClass()) {
+            return false;
+        }
+
+        BaseObj b = (BaseObj) obj;
+        return mID == b.mID;
+    }
+}
+
diff --git a/androidx/renderscript/Byte2.java b/androidx/renderscript/Byte2.java
new file mode 100644
index 0000000..cf738f4
--- /dev/null
+++ b/androidx/renderscript/Byte2.java
@@ -0,0 +1,42 @@
+/*
+ * 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript byte2 type back to the Android system.
+ *
+ **/
+public class Byte2 {
+    public Byte2() {
+    }
+
+    public Byte2(byte initX, byte initY) {
+        x = initX;
+        y = initY;
+    }
+
+    public byte x;
+    public byte y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Byte3.java b/androidx/renderscript/Byte3.java
new file mode 100644
index 0000000..559e34a
--- /dev/null
+++ b/androidx/renderscript/Byte3.java
@@ -0,0 +1,44 @@
+/*
+ * 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript byte3 type back to the Android system.
+ *
+ **/
+public class Byte3 {
+    public Byte3() {
+    }
+
+    public Byte3(byte initX, byte initY, byte initZ) {
+        x = initX;
+        y = initY;
+        z = initZ;
+    }
+
+    public byte x;
+    public byte y;
+    public byte z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Byte4.java b/androidx/renderscript/Byte4.java
new file mode 100644
index 0000000..0a71e63
--- /dev/null
+++ b/androidx/renderscript/Byte4.java
@@ -0,0 +1,45 @@
+/*
+ * 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript byte4 type back to the Android system.
+ *
+ **/
+public class Byte4 {
+    public Byte4() {
+    }
+
+    public Byte4(byte initX, byte initY, byte initZ, byte initW) {
+        x = initX;
+        y = initY;
+        z = initZ;
+        w = initW;
+    }
+
+    public byte x;
+    public byte y;
+    public byte z;
+    public byte w;
+}
+
+
+
diff --git a/androidx/renderscript/Double2.java b/androidx/renderscript/Double2.java
new file mode 100644
index 0000000..9abcd01
--- /dev/null
+++ b/androidx/renderscript/Double2.java
@@ -0,0 +1,43 @@
+/*
+ * 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript double2 type back
+ * to the Android system.
+ *
+ **/
+public class Double2 {
+    public Double2() {
+    }
+
+    public Double2(double initX, double initY) {
+        x = initX;
+        y = initY;
+    }
+
+    public double x;
+    public double y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Double3.java b/androidx/renderscript/Double3.java
new file mode 100644
index 0000000..0d07a50
--- /dev/null
+++ b/androidx/renderscript/Double3.java
@@ -0,0 +1,45 @@
+/*
+ * 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript double3 type back
+ * to the Android system.
+ *
+ **/
+public class Double3 {
+    public Double3() {
+    }
+
+    public Double3(double initX, double initY, double initZ) {
+        x = initX;
+        y = initY;
+        z = initZ;
+    }
+
+    public double x;
+    public double y;
+    public double z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Double4.java b/androidx/renderscript/Double4.java
new file mode 100644
index 0000000..3350abf
--- /dev/null
+++ b/androidx/renderscript/Double4.java
@@ -0,0 +1,46 @@
+/*
+ * 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript double4 type back
+ * to the Android system.
+ *
+ **/
+public class Double4 {
+    public Double4() {
+    }
+
+    public Double4(double initX, double initY, double initZ, double initW) {
+        x = initX;
+        y = initY;
+        z = initZ;
+        w = initW;
+    }
+
+    public double x;
+    public double y;
+    public double z;
+    public double w;
+}
+
+
+
diff --git a/androidx/renderscript/Element.java b/androidx/renderscript/Element.java
new file mode 100644
index 0000000..44dbc61
--- /dev/null
+++ b/androidx/renderscript/Element.java
@@ -0,0 +1,1020 @@
+/*
+ * Copyright (C) 2013 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 androidx.renderscript;
+
+import java.lang.reflect.Field;
+
+import android.util.Log;
+
+/**
+ * <p>An Element represents one item within an {@link
+ * androidx.renderscript.Allocation}.  An Element is roughly
+ * equivalent to a C type in a RenderScript kernel. Elements may be basic or
+ * complex. Some basic elements are</p> <ul> <li>A single float value
+ * (equivalent to a float in a kernel)</li> <li>A four-element float vector
+ * (equivalent to a float4 in a kernel)</li> <li>An unsigned 32-bit integer
+ * (equivalent to an unsigned int in a kernel)</li> <li>A single signed 8-bit
+ * integer (equivalent to a char in a kernel)</li> </ul> <p>A complex element is
+ * roughly equivalent to a C struct and contains a number of basic or complex
+ * Elements. From Java code, a complex element contains a list of sub-elements
+ * and names that represents a particular data structure. Structs used in RS
+ * scripts are available to Java code by using the
+ * {@code ScriptField_structname} class that is reflected from a particular
+ * script.</p>
+ *
+ * <p>Basic Elements are comprised of a {@link
+ * androidx.renderscript.Element.DataType} and a {@link
+ * androidx.renderscript.Element.DataKind}. The DataType encodes C
+ * type information of an Element, while the DataKind encodes how that Element
+ * should be interpreted by a {@link androidx.renderscript.Sampler}.
+ * Note that {@link androidx.renderscript.Allocation} objects with
+ * DataKind {@link androidx.renderscript.Element.DataKind#USER} cannot
+ * be used as input for a {@link androidx.renderscript.Sampler}. In
+ * general, {@link androidx.renderscript.Allocation} objects that are
+ * intended for use with a {@link androidx.renderscript.Sampler}
+ * should use bitmap-derived Elements such as
+ * {@link androidx.renderscript.Element#RGBA_8888} or {@link
+ * androidx.renderscript#Element.A_8}.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating an application that uses RenderScript,
+ * read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
+ * developer guide.</p>
+ * </div>
+ **/
+public class Element extends BaseObj {
+    int mSize;
+    Element[] mElements;
+    String[] mElementNames;
+    int[] mArraySizes;
+    int[] mOffsetInBytes;
+    int[] mVisibleElementMap;
+
+    DataType mType;
+    DataKind mKind;
+    boolean mNormalized;
+    int mVectorSize;
+
+    private void updateVisibleSubElements() {
+        if (mElements == null) {
+            return;
+        }
+
+        int noPaddingFieldCount = 0;
+        int fieldCount = mElementNames.length;
+        // Find out how many elements are not padding
+        for (int ct = 0; ct < fieldCount; ct ++) {
+            if (mElementNames[ct].charAt(0) != '#') {
+                noPaddingFieldCount ++;
+            }
+        }
+        mVisibleElementMap = new int[noPaddingFieldCount];
+
+        // Make a map that points us at non-padding elements
+        for (int ct = 0, ctNoPadding = 0; ct < fieldCount; ct ++) {
+            if (mElementNames[ct].charAt(0) != '#') {
+                mVisibleElementMap[ctNoPadding ++] = ct;
+            }
+        }
+    }
+
+    /**
+    * @return element size in bytes
+    */
+    public int getBytesSize() {
+        return mSize;
+    }
+
+    /**
+    * Returns the number of vector components. 2 for float2, 4 for
+    * float4, etc.
+    * @return element vector size
+    */
+    public int getVectorSize() {
+        return mVectorSize;
+    }
+
+
+    /**
+     * DataType represents the basic type information for a basic element.  The
+     * naming convention follows.  For numeric types it is FLOAT,
+     * SIGNED, or UNSIGNED followed by the _BITS where BITS is the
+     * size of the data.  BOOLEAN is a true / false (1,0)
+     * represented in an 8 bit container.  The UNSIGNED variants
+     * with multiple bit definitions are for packed graphical data
+     * formats and represent vectors with per vector member sizes
+     * which are treated as a single unit for packing and alignment
+     * purposes.
+     *
+     * MATRIX the three matrix types contain FLOAT_32 elements and are treated
+     * as 32 bits for alignment purposes.
+     *
+     * RS_* objects.  32 bit opaque handles.
+     */
+    public enum DataType {
+        NONE (0, 0),
+        //FLOAT_16 (1, 2),
+        FLOAT_32 (2, 4),
+        FLOAT_64 (3, 8),
+        SIGNED_8 (4, 1),
+        SIGNED_16 (5, 2),
+        SIGNED_32 (6, 4),
+        SIGNED_64 (7, 8),
+        UNSIGNED_8 (8, 1),
+        UNSIGNED_16 (9, 2),
+        UNSIGNED_32 (10, 4),
+        UNSIGNED_64 (11, 8),
+
+        BOOLEAN(12, 1),
+
+        UNSIGNED_5_6_5 (13, 2),
+        UNSIGNED_5_5_5_1 (14, 2),
+        UNSIGNED_4_4_4_4 (15, 2),
+
+        MATRIX_4X4 (16, 64),
+        MATRIX_3X3 (17, 36),
+        MATRIX_2X2 (18, 16),
+
+        RS_ELEMENT (1000),
+        RS_TYPE (1001),
+        RS_ALLOCATION (1002),
+        RS_SAMPLER (1003),
+        RS_SCRIPT (1004);
+
+        int mID;
+        int mSize;
+        DataType(int id, int size) {
+            mID = id;
+            mSize = size;
+        }
+
+        DataType(int id) {
+            mID = id;
+            mSize = 4;
+            if (RenderScript.sPointerSize == 8) {
+                mSize = 32;
+            }
+        }
+    }
+
+    /**
+     * The special interpretation of the data if required.  This is primarly
+     * useful for graphical data.  USER indicates no special interpretation is
+     * expected.  PIXEL is used in conjunction with the standard data types for
+     * representing texture formats.
+     */
+    public enum DataKind {
+        USER (0),
+
+        PIXEL_L (7),
+        PIXEL_A (8),
+        PIXEL_LA (9),
+        PIXEL_RGB (10),
+        PIXEL_RGBA (11),
+        PIXEL_DEPTH (12),
+        PIXEL_YUV(13);
+
+        int mID;
+        DataKind(int id) {
+            mID = id;
+        }
+    }
+
+    /**
+     * Return if a element is too complex for use as a data source for a Mesh or
+     * a Program.
+     *
+     * @return boolean
+     */
+    public boolean isComplex() {
+        if (mElements == null) {
+            return false;
+        }
+        for (int ct=0; ct < mElements.length; ct++) {
+            if (mElements[ct].mElements != null) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+    * Elements could be simple, such as an int or a float, or a
+    * structure with multiple sub elements, such as a collection of
+    * floats, float2, float4. This function returns zero for simple
+    * elements or the number of sub-elements otherwise.
+    * @return number of sub-elements in this element
+    */
+    public int getSubElementCount() {
+        if (mVisibleElementMap == null) {
+            return 0;
+        }
+        return mVisibleElementMap.length;
+    }
+
+    /**
+    * For complex elements, this function will return the
+    * sub-element at index
+    * @param index index of the sub-element to return
+    * @return sub-element in this element at given index
+    */
+    public Element getSubElement(int index) {
+        if (mVisibleElementMap == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mVisibleElementMap.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mElements[mVisibleElementMap[index]];
+    }
+
+    /**
+    * For complex elements, this function will return the
+    * sub-element name at index
+    * @param index index of the sub-element
+    * @return sub-element in this element at given index
+    */
+    public String getSubElementName(int index) {
+        if (mVisibleElementMap == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mVisibleElementMap.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mElementNames[mVisibleElementMap[index]];
+    }
+
+    /**
+    * For complex elements, some sub-elements could be statically
+    * sized arrays. This function will return the array size for
+    * sub-element at index
+    * @param index index of the sub-element
+    * @return array size of sub-element in this element at given index
+    */
+    public int getSubElementArraySize(int index) {
+        if (mVisibleElementMap == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mVisibleElementMap.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mArraySizes[mVisibleElementMap[index]];
+    }
+
+    /**
+    * This function specifies the location of a sub-element within
+    * the element
+    * @param index index of the sub-element
+    * @return offset in bytes of sub-element in this element at given index
+    */
+    public int getSubElementOffsetBytes(int index) {
+        if (mVisibleElementMap == null) {
+            throw new RSIllegalArgumentException("Element contains no sub-elements");
+        }
+        if (index < 0 || index >= mVisibleElementMap.length) {
+            throw new RSIllegalArgumentException("Illegal sub-element index");
+        }
+        return mOffsetInBytes[mVisibleElementMap[index]];
+    }
+
+    /**
+    * @return element data type
+    */
+    public DataType getDataType() {
+        return mType;
+    }
+
+    /**
+    * @return element data kind
+    */
+    public DataKind getDataKind() {
+        return mKind;
+    }
+
+    /**
+     * Utility function for returning an Element containing a single Boolean.
+     *
+     * @param rs Context to which the element will belong.
+     *
+     * @return Element
+     */
+    public static Element BOOLEAN(RenderScript rs) {
+        if(rs.mElement_BOOLEAN == null) {
+            rs.mElement_BOOLEAN = createUser(rs, DataType.BOOLEAN);
+        }
+        return rs.mElement_BOOLEAN;
+    }
+
+    /**
+     * Utility function for returning an Element containing a single UNSIGNED_8.
+     *
+     * @param rs Context to which the element will belong.
+     *
+     * @return Element
+     */
+    public static Element U8(RenderScript rs) {
+        if(rs.mElement_U8 == null) {
+            rs.mElement_U8 = createUser(rs, DataType.UNSIGNED_8);
+        }
+        return rs.mElement_U8;
+    }
+
+    /**
+     * Utility function for returning an Element containing a single SIGNED_8.
+     *
+     * @param rs Context to which the element will belong.
+     *
+     * @return Element
+     */
+    public static Element I8(RenderScript rs) {
+        if(rs.mElement_I8 == null) {
+            rs.mElement_I8 = createUser(rs, DataType.SIGNED_8);
+        }
+        return rs.mElement_I8;
+    }
+
+    public static Element U16(RenderScript rs) {
+        if(rs.mElement_U16 == null) {
+            rs.mElement_U16 = createUser(rs, DataType.UNSIGNED_16);
+        }
+        return rs.mElement_U16;
+    }
+
+    public static Element I16(RenderScript rs) {
+        if(rs.mElement_I16 == null) {
+            rs.mElement_I16 = createUser(rs, DataType.SIGNED_16);
+        }
+        return rs.mElement_I16;
+    }
+
+    public static Element U32(RenderScript rs) {
+        if(rs.mElement_U32 == null) {
+            rs.mElement_U32 = createUser(rs, DataType.UNSIGNED_32);
+        }
+        return rs.mElement_U32;
+    }
+
+    public static Element I32(RenderScript rs) {
+        if(rs.mElement_I32 == null) {
+            rs.mElement_I32 = createUser(rs, DataType.SIGNED_32);
+        }
+        return rs.mElement_I32;
+    }
+
+    public static Element U64(RenderScript rs) {
+        if(rs.mElement_U64 == null) {
+            rs.mElement_U64 = createUser(rs, DataType.UNSIGNED_64);
+        }
+        return rs.mElement_U64;
+    }
+
+    public static Element I64(RenderScript rs) {
+        if(rs.mElement_I64 == null) {
+            rs.mElement_I64 = createUser(rs, DataType.SIGNED_64);
+        }
+        return rs.mElement_I64;
+    }
+
+    public static Element F32(RenderScript rs) {
+        if(rs.mElement_F32 == null) {
+            rs.mElement_F32 = createUser(rs, DataType.FLOAT_32);
+        }
+        return rs.mElement_F32;
+    }
+
+    public static Element F64(RenderScript rs) {
+        if(rs.mElement_F64 == null) {
+            rs.mElement_F64 = createUser(rs, DataType.FLOAT_64);
+        }
+        return rs.mElement_F64;
+    }
+
+    public static Element ELEMENT(RenderScript rs) {
+        if(rs.mElement_ELEMENT == null) {
+            rs.mElement_ELEMENT = createUser(rs, DataType.RS_ELEMENT);
+        }
+        return rs.mElement_ELEMENT;
+    }
+
+    public static Element TYPE(RenderScript rs) {
+        if(rs.mElement_TYPE == null) {
+            rs.mElement_TYPE = createUser(rs, DataType.RS_TYPE);
+        }
+        return rs.mElement_TYPE;
+    }
+
+    public static Element ALLOCATION(RenderScript rs) {
+        if(rs.mElement_ALLOCATION == null) {
+            rs.mElement_ALLOCATION = createUser(rs, DataType.RS_ALLOCATION);
+        }
+        return rs.mElement_ALLOCATION;
+    }
+
+    public static Element SAMPLER(RenderScript rs) {
+        if(rs.mElement_SAMPLER == null) {
+            rs.mElement_SAMPLER = createUser(rs, DataType.RS_SAMPLER);
+        }
+        return rs.mElement_SAMPLER;
+    }
+
+    public static Element SCRIPT(RenderScript rs) {
+        if(rs.mElement_SCRIPT == null) {
+            rs.mElement_SCRIPT = createUser(rs, DataType.RS_SCRIPT);
+        }
+        return rs.mElement_SCRIPT;
+    }
+
+
+    public static Element A_8(RenderScript rs) {
+        if(rs.mElement_A_8 == null) {
+            rs.mElement_A_8 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_A);
+        }
+        return rs.mElement_A_8;
+    }
+
+    public static Element RGB_565(RenderScript rs) {
+        if(rs.mElement_RGB_565 == null) {
+            rs.mElement_RGB_565 = createPixel(rs, DataType.UNSIGNED_5_6_5, DataKind.PIXEL_RGB);
+        }
+        return rs.mElement_RGB_565;
+    }
+
+    public static Element RGB_888(RenderScript rs) {
+        if(rs.mElement_RGB_888 == null) {
+            rs.mElement_RGB_888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGB);
+        }
+        return rs.mElement_RGB_888;
+    }
+
+    public static Element RGBA_5551(RenderScript rs) {
+        if(rs.mElement_RGBA_5551 == null) {
+            rs.mElement_RGBA_5551 = createPixel(rs, DataType.UNSIGNED_5_5_5_1, DataKind.PIXEL_RGBA);
+        }
+        return rs.mElement_RGBA_5551;
+    }
+
+    public static Element RGBA_4444(RenderScript rs) {
+        if(rs.mElement_RGBA_4444 == null) {
+            rs.mElement_RGBA_4444 = createPixel(rs, DataType.UNSIGNED_4_4_4_4, DataKind.PIXEL_RGBA);
+        }
+        return rs.mElement_RGBA_4444;
+    }
+
+    public static Element RGBA_8888(RenderScript rs) {
+        if(rs.mElement_RGBA_8888 == null) {
+            rs.mElement_RGBA_8888 = createPixel(rs, DataType.UNSIGNED_8, DataKind.PIXEL_RGBA);
+        }
+        return rs.mElement_RGBA_8888;
+    }
+
+    public static Element F32_2(RenderScript rs) {
+        if(rs.mElement_FLOAT_2 == null) {
+            rs.mElement_FLOAT_2 = createVector(rs, DataType.FLOAT_32, 2);
+        }
+        return rs.mElement_FLOAT_2;
+    }
+
+    public static Element F32_3(RenderScript rs) {
+        if(rs.mElement_FLOAT_3 == null) {
+            rs.mElement_FLOAT_3 = createVector(rs, DataType.FLOAT_32, 3);
+        }
+        return rs.mElement_FLOAT_3;
+    }
+
+    public static Element F32_4(RenderScript rs) {
+        if(rs.mElement_FLOAT_4 == null) {
+            rs.mElement_FLOAT_4 = createVector(rs, DataType.FLOAT_32, 4);
+        }
+        return rs.mElement_FLOAT_4;
+    }
+
+    public static Element F64_2(RenderScript rs) {
+        if(rs.mElement_DOUBLE_2 == null) {
+            rs.mElement_DOUBLE_2 = createVector(rs, DataType.FLOAT_64, 2);
+        }
+        return rs.mElement_DOUBLE_2;
+    }
+
+    public static Element F64_3(RenderScript rs) {
+        if(rs.mElement_DOUBLE_3 == null) {
+            rs.mElement_DOUBLE_3 = createVector(rs, DataType.FLOAT_64, 3);
+        }
+        return rs.mElement_DOUBLE_3;
+    }
+
+    public static Element F64_4(RenderScript rs) {
+        if(rs.mElement_DOUBLE_4 == null) {
+            rs.mElement_DOUBLE_4 = createVector(rs, DataType.FLOAT_64, 4);
+        }
+        return rs.mElement_DOUBLE_4;
+    }
+
+    public static Element U8_2(RenderScript rs) {
+        if(rs.mElement_UCHAR_2 == null) {
+            rs.mElement_UCHAR_2 = createVector(rs, DataType.UNSIGNED_8, 2);
+        }
+        return rs.mElement_UCHAR_2;
+    }
+
+    public static Element U8_3(RenderScript rs) {
+        if(rs.mElement_UCHAR_3 == null) {
+            rs.mElement_UCHAR_3 = createVector(rs, DataType.UNSIGNED_8, 3);
+        }
+        return rs.mElement_UCHAR_3;
+    }
+
+    public static Element U8_4(RenderScript rs) {
+        if(rs.mElement_UCHAR_4 == null) {
+            rs.mElement_UCHAR_4 = createVector(rs, DataType.UNSIGNED_8, 4);
+        }
+        return rs.mElement_UCHAR_4;
+    }
+
+    public static Element I8_2(RenderScript rs) {
+        if(rs.mElement_CHAR_2 == null) {
+            rs.mElement_CHAR_2 = createVector(rs, DataType.SIGNED_8, 2);
+        }
+        return rs.mElement_CHAR_2;
+    }
+
+    public static Element I8_3(RenderScript rs) {
+        if(rs.mElement_CHAR_3 == null) {
+            rs.mElement_CHAR_3 = createVector(rs, DataType.SIGNED_8, 3);
+        }
+        return rs.mElement_CHAR_3;
+    }
+
+    public static Element I8_4(RenderScript rs) {
+        if(rs.mElement_CHAR_4 == null) {
+            rs.mElement_CHAR_4 = createVector(rs, DataType.SIGNED_8, 4);
+        }
+        return rs.mElement_CHAR_4;
+    }
+
+    public static Element U16_2(RenderScript rs) {
+        if(rs.mElement_USHORT_2 == null) {
+            rs.mElement_USHORT_2 = createVector(rs, DataType.UNSIGNED_16, 2);
+        }
+        return rs.mElement_USHORT_2;
+    }
+
+    public static Element U16_3(RenderScript rs) {
+        if(rs.mElement_USHORT_3 == null) {
+            rs.mElement_USHORT_3 = createVector(rs, DataType.UNSIGNED_16, 3);
+        }
+        return rs.mElement_USHORT_3;
+    }
+
+    public static Element U16_4(RenderScript rs) {
+        if(rs.mElement_USHORT_4 == null) {
+            rs.mElement_USHORT_4 = createVector(rs, DataType.UNSIGNED_16, 4);
+        }
+        return rs.mElement_USHORT_4;
+    }
+
+    public static Element I16_2(RenderScript rs) {
+        if(rs.mElement_SHORT_2 == null) {
+            rs.mElement_SHORT_2 = createVector(rs, DataType.SIGNED_16, 2);
+        }
+        return rs.mElement_SHORT_2;
+    }
+
+    public static Element I16_3(RenderScript rs) {
+        if(rs.mElement_SHORT_3 == null) {
+            rs.mElement_SHORT_3 = createVector(rs, DataType.SIGNED_16, 3);
+        }
+        return rs.mElement_SHORT_3;
+    }
+
+    public static Element I16_4(RenderScript rs) {
+        if(rs.mElement_SHORT_4 == null) {
+            rs.mElement_SHORT_4 = createVector(rs, DataType.SIGNED_16, 4);
+        }
+        return rs.mElement_SHORT_4;
+    }
+
+    public static Element U32_2(RenderScript rs) {
+        if(rs.mElement_UINT_2 == null) {
+            rs.mElement_UINT_2 = createVector(rs, DataType.UNSIGNED_32, 2);
+        }
+        return rs.mElement_UINT_2;
+    }
+
+    public static Element U32_3(RenderScript rs) {
+        if(rs.mElement_UINT_3 == null) {
+            rs.mElement_UINT_3 = createVector(rs, DataType.UNSIGNED_32, 3);
+        }
+        return rs.mElement_UINT_3;
+    }
+
+    public static Element U32_4(RenderScript rs) {
+        if(rs.mElement_UINT_4 == null) {
+            rs.mElement_UINT_4 = createVector(rs, DataType.UNSIGNED_32, 4);
+        }
+        return rs.mElement_UINT_4;
+    }
+
+    public static Element I32_2(RenderScript rs) {
+        if(rs.mElement_INT_2 == null) {
+            rs.mElement_INT_2 = createVector(rs, DataType.SIGNED_32, 2);
+        }
+        return rs.mElement_INT_2;
+    }
+
+    public static Element I32_3(RenderScript rs) {
+        if(rs.mElement_INT_3 == null) {
+            rs.mElement_INT_3 = createVector(rs, DataType.SIGNED_32, 3);
+        }
+        return rs.mElement_INT_3;
+    }
+
+    public static Element I32_4(RenderScript rs) {
+        if(rs.mElement_INT_4 == null) {
+            rs.mElement_INT_4 = createVector(rs, DataType.SIGNED_32, 4);
+        }
+        return rs.mElement_INT_4;
+    }
+
+    public static Element U64_2(RenderScript rs) {
+        if(rs.mElement_ULONG_2 == null) {
+            rs.mElement_ULONG_2 = createVector(rs, DataType.UNSIGNED_64, 2);
+        }
+        return rs.mElement_ULONG_2;
+    }
+
+    public static Element U64_3(RenderScript rs) {
+        if(rs.mElement_ULONG_3 == null) {
+            rs.mElement_ULONG_3 = createVector(rs, DataType.UNSIGNED_64, 3);
+        }
+        return rs.mElement_ULONG_3;
+    }
+
+    public static Element U64_4(RenderScript rs) {
+        if(rs.mElement_ULONG_4 == null) {
+            rs.mElement_ULONG_4 = createVector(rs, DataType.UNSIGNED_64, 4);
+        }
+        return rs.mElement_ULONG_4;
+    }
+
+    public static Element I64_2(RenderScript rs) {
+        if(rs.mElement_LONG_2 == null) {
+            rs.mElement_LONG_2 = createVector(rs, DataType.SIGNED_64, 2);
+        }
+        return rs.mElement_LONG_2;
+    }
+
+    public static Element I64_3(RenderScript rs) {
+        if(rs.mElement_LONG_3 == null) {
+            rs.mElement_LONG_3 = createVector(rs, DataType.SIGNED_64, 3);
+        }
+        return rs.mElement_LONG_3;
+    }
+
+    public static Element I64_4(RenderScript rs) {
+        if(rs.mElement_LONG_4 == null) {
+            rs.mElement_LONG_4 = createVector(rs, DataType.SIGNED_64, 4);
+        }
+        return rs.mElement_LONG_4;
+    }
+
+    public static Element MATRIX_4X4(RenderScript rs) {
+        if(rs.mElement_MATRIX_4X4 == null) {
+            rs.mElement_MATRIX_4X4 = createUser(rs, DataType.MATRIX_4X4);
+        }
+        return rs.mElement_MATRIX_4X4;
+    }
+
+    public static Element MATRIX_3X3(RenderScript rs) {
+        if(rs.mElement_MATRIX_3X3 == null) {
+            rs.mElement_MATRIX_3X3 = createUser(rs, DataType.MATRIX_3X3);
+        }
+        return rs.mElement_MATRIX_3X3;
+    }
+
+    public static Element MATRIX_2X2(RenderScript rs) {
+        if(rs.mElement_MATRIX_2X2 == null) {
+            rs.mElement_MATRIX_2X2 = createUser(rs, DataType.MATRIX_2X2);
+        }
+        return rs.mElement_MATRIX_2X2;
+    }
+
+    Element(long id, RenderScript rs, Element[] e, String[] n, int[] as) {
+        super(id, rs);
+        mSize = 0;
+        mVectorSize = 1;
+        mElements = e;
+        mElementNames = n;
+        mArraySizes = as;
+        mType = DataType.NONE;
+        mKind = DataKind.USER;
+        mOffsetInBytes = new int[mElements.length];
+        for (int ct = 0; ct < mElements.length; ct++ ) {
+            mOffsetInBytes[ct] = mSize;
+            mSize += mElements[ct].mSize * mArraySizes[ct];
+        }
+        updateVisibleSubElements();
+    }
+
+    Element(long id, RenderScript rs, DataType dt, DataKind dk, boolean norm, int size) {
+        super(id, rs);
+        if ((dt != DataType.UNSIGNED_5_6_5) &&
+            (dt != DataType.UNSIGNED_4_4_4_4) &&
+            (dt != DataType.UNSIGNED_5_5_5_1)) {
+            if (size == 3) {
+                mSize = dt.mSize * 4;
+            } else {
+                mSize = dt.mSize * size;
+            }
+        } else {
+            mSize = dt.mSize;
+        }
+        mType = dt;
+        mKind = dk;
+        mNormalized = norm;
+        mVectorSize = size;
+    }
+
+    Element(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /*
+     * Get an identical dummy Element for Compat Context
+     *
+     */
+    public long getDummyElement(RenderScript mRS) {
+        return mRS.nIncElementCreate(mType.mID, mKind.mID, mNormalized, mVectorSize);
+    }
+    /**
+     * Create a custom Element of the specified DataType.  The DataKind will be
+     * set to USER and the vector size to 1 indicating non-vector.
+     *
+     * @param rs The context associated with the new Element.
+     * @param dt The DataType for the new element.
+     * @return Element
+     */
+    static Element createUser(RenderScript rs, DataType dt) {
+        DataKind dk = DataKind.USER;
+        boolean norm = false;
+        int vecSize = 1;
+        long id = rs.nElementCreate(dt.mID, dk.mID, norm, vecSize);
+        return new Element(id, rs, dt, dk, norm, vecSize);
+    }
+
+    /**
+     * Create a custom vector element of the specified DataType and vector size.
+     * DataKind will be set to USER. Only primitive types (FLOAT_32, FLOAT_64,
+     * SIGNED_8, SIGNED_16, SIGNED_32, SIGNED_64, UNSIGNED_8, UNSIGNED_16,
+     * UNSIGNED_32, UNSIGNED_64, BOOLEAN) are supported.
+     *
+     * @param rs The context associated with the new Element.
+     * @param dt The DataType for the new Element.
+     * @param size Vector size for the new Element.  Range 2-4 inclusive
+     *             supported.
+     *
+     * @return Element
+     */
+    public static Element createVector(RenderScript rs, DataType dt, int size) {
+        if (size < 2 || size > 4) {
+            throw new RSIllegalArgumentException("Vector size out of range 2-4.");
+        }
+
+        switch (dt) {
+        // Support only primitive integer/float/boolean types as vectors.
+        case FLOAT_32:
+        case FLOAT_64:
+        case SIGNED_8:
+        case SIGNED_16:
+        case SIGNED_32:
+        case SIGNED_64:
+        case UNSIGNED_8:
+        case UNSIGNED_16:
+        case UNSIGNED_32:
+        case UNSIGNED_64:
+        case BOOLEAN: {
+            DataKind dk = DataKind.USER;
+            boolean norm = false;
+            long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
+            return new Element(id, rs, dt, dk, norm, size);
+        }
+
+        default: {
+            throw new RSIllegalArgumentException("Cannot create vector of " +
+                "non-primitive type.");
+        }
+        }
+    }
+
+    /**
+     * Create a new pixel Element type.  A matching DataType and DataKind must
+     * be provided.  The DataType and DataKind must contain the same number of
+     * components.  Vector size will be set to 1.
+     *
+     * @param rs The context associated with the new Element.
+     * @param dt The DataType for the new element.
+     * @param dk The DataKind to specify the mapping of each component in the
+     *           DataType.
+     *
+     * @return Element
+     */
+    public static Element createPixel(RenderScript rs, DataType dt, DataKind dk) {
+        if (!(dk == DataKind.PIXEL_L ||
+              dk == DataKind.PIXEL_A ||
+              dk == DataKind.PIXEL_LA ||
+              dk == DataKind.PIXEL_RGB ||
+              dk == DataKind.PIXEL_RGBA ||
+              dk == DataKind.PIXEL_DEPTH ||
+              dk == DataKind.PIXEL_YUV)) {
+            throw new RSIllegalArgumentException("Unsupported DataKind");
+        }
+        if (!(dt == DataType.UNSIGNED_8 ||
+              dt == DataType.UNSIGNED_16 ||
+              dt == DataType.UNSIGNED_5_6_5 ||
+              dt == DataType.UNSIGNED_4_4_4_4 ||
+              dt == DataType.UNSIGNED_5_5_5_1)) {
+            throw new RSIllegalArgumentException("Unsupported DataType");
+        }
+        if (dt == DataType.UNSIGNED_5_6_5 && dk != DataKind.PIXEL_RGB) {
+            throw new RSIllegalArgumentException("Bad kind and type combo");
+        }
+        if (dt == DataType.UNSIGNED_5_5_5_1 && dk != DataKind.PIXEL_RGBA) {
+            throw new RSIllegalArgumentException("Bad kind and type combo");
+        }
+        if (dt == DataType.UNSIGNED_4_4_4_4 && dk != DataKind.PIXEL_RGBA) {
+            throw new RSIllegalArgumentException("Bad kind and type combo");
+        }
+        if (dt == DataType.UNSIGNED_16 &&
+            dk != DataKind.PIXEL_DEPTH) {
+            throw new RSIllegalArgumentException("Bad kind and type combo");
+        }
+
+        int size = 1;
+        switch (dk) {
+        case PIXEL_LA:
+            size = 2;
+            break;
+        case PIXEL_RGB:
+            size = 3;
+            break;
+        case PIXEL_RGBA:
+            size = 4;
+            break;
+        }
+
+        boolean norm = true;
+        long id = rs.nElementCreate(dt.mID, dk.mID, norm, size);
+        return new Element(id, rs, dt, dk, norm, size);
+    }
+
+    /**
+     * Check if the current Element is compatible with another Element.
+     * Primitive Elements are compatible if they share the same underlying
+     * size and type (i.e. U8 is compatible with A_8). User-defined Elements
+     * must be equal in order to be compatible. This requires strict name
+     * equivalence for all sub-Elements (in addition to structural equivalence).
+     *
+     * @param e The Element to check compatibility with.
+     *
+     * @return boolean true if the Elements are compatible, otherwise false.
+     */
+    public boolean isCompatible(Element e) {
+        // Try strict BaseObj equality to start with.
+        if (this.equals(e)) {
+            return true;
+        }
+
+        // Ignore mKind because it is allowed to be different (user vs. pixel).
+        // We also ignore mNormalized because it can be different. The mType
+        // field must not be NONE since we require name equivalence for
+        // all user-created Elements.
+        return ((mSize == e.mSize) &&
+                (mType != DataType.NONE) &&
+                (mType == e.mType) &&
+                (mVectorSize == e.mVectorSize));
+    }
+
+    /**
+     * Builder class for producing complex elements with matching field and name
+     * pairs.  The builder starts empty.  The order in which elements are added
+     * is retained for the layout in memory.
+     *
+     */
+    public static class Builder {
+
+        RenderScript mRS;
+        Element[] mElements;
+        String[] mElementNames;
+        int[] mArraySizes;
+        int mCount;
+        int mSkipPadding;
+
+        /**
+         * Create a builder object.
+         *
+         * @param rs
+         */
+        public Builder(RenderScript rs) {
+            mRS = rs;
+            mCount = 0;
+            mElements = new Element[8];
+            mElementNames = new String[8];
+            mArraySizes = new int[8];
+        }
+
+        /**
+         * Add an array of elements to this element.
+         *
+         * @param element
+         * @param name
+         * @param arraySize
+         */
+        public Builder add(Element element, String name, int arraySize) {
+            if (arraySize < 1) {
+                throw new RSIllegalArgumentException("Array size cannot be less than 1.");
+            }
+
+            // Skip padding fields after a vector 3 type.
+            if (mSkipPadding != 0) {
+                if (name.startsWith("#padding_")) {
+                    mSkipPadding = 0;
+                    return this;
+                }
+            }
+
+            if (element.mVectorSize == 3) {
+                mSkipPadding = 1;
+            } else {
+                mSkipPadding = 0;
+            }
+
+            if(mCount == mElements.length) {
+                Element[] e = new Element[mCount + 8];
+                String[] s = new String[mCount + 8];
+                int[] as = new int[mCount + 8];
+                System.arraycopy(mElements, 0, e, 0, mCount);
+                System.arraycopy(mElementNames, 0, s, 0, mCount);
+                System.arraycopy(mArraySizes, 0, as, 0, mCount);
+                mElements = e;
+                mElementNames = s;
+                mArraySizes = as;
+            }
+            mElements[mCount] = element;
+            mElementNames[mCount] = name;
+            mArraySizes[mCount] = arraySize;
+            mCount++;
+
+            return this;
+        }
+
+        /**
+         * Add a single element to this Element.
+         *
+         * @param element
+         * @param name
+         */
+        public Builder add(Element element, String name) {
+            return add(element, name, 1);
+        }
+
+        /**
+         * Create the element from this builder.
+         *
+         *
+         * @return Element
+         */
+        public Element create() {
+            mRS.validate();
+            Element[] ein = new Element[mCount];
+            String[] sin = new String[mCount];
+            int[] asin = new int[mCount];
+            java.lang.System.arraycopy(mElements, 0, ein, 0, mCount);
+            java.lang.System.arraycopy(mElementNames, 0, sin, 0, mCount);
+            java.lang.System.arraycopy(mArraySizes, 0, asin, 0, mCount);
+
+            long[] ids = new long[ein.length];
+            for (int ct = 0; ct < ein.length; ct++ ) {
+                ids[ct] = ein[ct].getID(mRS);
+            }
+
+            long id = mRS.nElementCreate2(ids, sin, asin);
+            return new Element(id, mRS, ein, sin, asin);
+        }
+    }
+}
+
diff --git a/androidx/renderscript/FieldPacker.java b/androidx/renderscript/FieldPacker.java
new file mode 100644
index 0000000..34e9ae6
--- /dev/null
+++ b/androidx/renderscript/FieldPacker.java
@@ -0,0 +1,946 @@
+/*
+ * 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 androidx.renderscript;
+
+import androidx.renderscript.RenderScript;
+import java.util.BitSet;
+
+/**
+ * Utility class for packing arguments and structures from Android system objects to
+ * RenderScript objects.
+ *
+ * This class is only intended to be used to support the
+ * reflected code generated by the RS tool chain.  It should not
+ * be called directly.
+ *
+ **/
+public class FieldPacker {
+    public FieldPacker(int len) {
+        mPos = 0;
+        mLen = len;
+        mData = new byte[len];
+        mAlignment = new BitSet();
+    }
+
+    public FieldPacker(byte[] data) {
+        // Advance mPos to the end of the buffer, since we are copying in the
+        // full data input.
+        mPos = data.length;
+        mLen = data.length;
+        mData = data;
+        mAlignment = new BitSet();
+        // TODO: We should either have an actual FieldPacker copy constructor
+        // or drop support for computing alignment like this. As it stands,
+        // subAlign() can never work correctly for copied FieldPacker objects.
+    }
+
+    static FieldPacker createFromArray(Object[] args) {
+        FieldPacker fp = new FieldPacker(RenderScript.sPointerSize * 8);
+        for (Object arg : args) {
+            fp.addSafely(arg);
+        }
+        fp.resize(fp.mPos);
+        return fp;
+    }
+
+    public void align(int v) {
+        if ((v <= 0) || ((v & (v - 1)) != 0)) {
+            throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
+        }
+
+        while ((mPos & (v - 1)) != 0) {
+            mAlignment.flip(mPos);
+            mData[mPos++] = 0;
+        }
+    }
+
+    public void subalign(int v) {
+        if ((v & (v - 1)) != 0) {
+            throw new RSIllegalArgumentException("argument must be a non-negative non-zero power of 2: " + v);
+        }
+
+        while ((mPos & (v - 1)) != 0) {
+            mPos--;
+        }
+
+        if (mPos > 0) {
+            while (mAlignment.get(mPos - 1) == true) {
+                mPos--;
+                mAlignment.flip(mPos);
+            }
+        }
+
+    }
+
+    public void reset() {
+        mPos = 0;
+    }
+    public void reset(int i) {
+        if ((i < 0) || (i > mLen)) {
+            throw new RSIllegalArgumentException("out of range argument: " + i);
+        }
+        mPos = i;
+    }
+
+    public void skip(int i) {
+        int res = mPos + i;
+        if ((res < 0) || (res > mLen)) {
+            throw new RSIllegalArgumentException("out of range argument: " + i);
+        }
+        mPos = res;
+    }
+
+    public void addI8(byte v) {
+        mData[mPos++] = v;
+    }
+
+    public byte subI8() {
+        subalign(1);
+        return mData[--mPos];
+    }
+
+    public void addI16(short v) {
+        align(2);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)(v >> 8);
+    }
+
+    public short subI16() {
+        subalign(2);
+        short v = 0;
+        v = (short)((mData[--mPos] & 0xff) << 8);
+        v = (short)(v | (short)(mData[--mPos] & 0xff));
+        return v;
+    }
+
+
+    public void addI32(int v) {
+        align(4);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)((v >> 8) & 0xff);
+        mData[mPos++] = (byte)((v >> 16) & 0xff);
+        mData[mPos++] = (byte)((v >> 24) & 0xff);
+    }
+
+    public int subI32() {
+        subalign(4);
+        int v = 0;
+        v = ((mData[--mPos] & 0xff) << 24);
+        v = v | ((mData[--mPos] & 0xff) << 16);
+        v = v | ((mData[--mPos] & 0xff) << 8);
+        v = v | ((mData[--mPos] & 0xff));
+        return v;
+    }
+
+
+    public void addI64(long v) {
+        align(8);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)((v >> 8) & 0xff);
+        mData[mPos++] = (byte)((v >> 16) & 0xff);
+        mData[mPos++] = (byte)((v >> 24) & 0xff);
+        mData[mPos++] = (byte)((v >> 32) & 0xff);
+        mData[mPos++] = (byte)((v >> 40) & 0xff);
+        mData[mPos++] = (byte)((v >> 48) & 0xff);
+        mData[mPos++] = (byte)((v >> 56) & 0xff);
+    }
+
+    public long subI64() {
+        subalign(8);
+        long v = 0;
+        byte x = 0;
+        x = ((mData[--mPos]));
+        v = (long)(v | (((long)x) & 0xff) << 56l);
+        x = ((mData[--mPos]));
+        v = (long)(v | (((long)x) & 0xff) << 48l);
+        x = ((mData[--mPos]));
+        v = (long)(v | (((long)x) & 0xff) << 40l);
+        x = ((mData[--mPos]));
+        v = (long)(v | (((long)x) & 0xff) << 32l);
+        x = ((mData[--mPos]));
+        v = (long)(v | (((long)x) & 0xff) << 24l);
+        x = ((mData[--mPos]));
+        v = (long)(v | (((long)x) & 0xff) << 16l);
+        x = ((mData[--mPos]));
+        v = (long)(v | (((long)x) & 0xff) << 8l);
+        x = ((mData[--mPos]));
+        v = (long)(v | (((long)x) & 0xff));
+        return v;
+    }
+
+    public void addU8(short v) {
+        if ((v < 0) || (v > 0xff)) {
+            android.util.Log.e("rs", "FieldPacker.addU8( " + v + " )");
+            throw new IllegalArgumentException("Saving value out of range for type");
+        }
+        mData[mPos++] = (byte)v;
+    }
+
+    public void addU16(int v) {
+        if ((v < 0) || (v > 0xffff)) {
+            android.util.Log.e("rs", "FieldPacker.addU16( " + v + " )");
+            throw new IllegalArgumentException("Saving value out of range for type");
+        }
+        align(2);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)(v >> 8);
+    }
+
+    public void addU32(long v) {
+        if ((v < 0) || (v > 0xffffffffL)) {
+            android.util.Log.e("rs", "FieldPacker.addU32( " + v + " )");
+            throw new IllegalArgumentException("Saving value out of range for type");
+        }
+        align(4);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)((v >> 8) & 0xff);
+        mData[mPos++] = (byte)((v >> 16) & 0xff);
+        mData[mPos++] = (byte)((v >> 24) & 0xff);
+    }
+
+    public void addU64(long v) {
+        if (v < 0) {
+            android.util.Log.e("rs", "FieldPacker.addU64( " + v + " )");
+            throw new IllegalArgumentException("Saving value out of range for type");
+        }
+        align(8);
+        mData[mPos++] = (byte)(v & 0xff);
+        mData[mPos++] = (byte)((v >> 8) & 0xff);
+        mData[mPos++] = (byte)((v >> 16) & 0xff);
+        mData[mPos++] = (byte)((v >> 24) & 0xff);
+        mData[mPos++] = (byte)((v >> 32) & 0xff);
+        mData[mPos++] = (byte)((v >> 40) & 0xff);
+        mData[mPos++] = (byte)((v >> 48) & 0xff);
+        mData[mPos++] = (byte)((v >> 56) & 0xff);
+    }
+
+    public void addF32(float v) {
+        addI32(Float.floatToRawIntBits(v));
+    }
+
+    public float subF32() {
+        return Float.intBitsToFloat(subI32());
+    }
+
+    public void addF64(double v) {
+        addI64(Double.doubleToRawLongBits(v));
+    }
+
+    public double subF64() {
+        return Double.longBitsToDouble(subI64());
+    }
+
+    public void addObj(BaseObj obj) {
+        if (obj != null) {
+            if (RenderScript.sPointerSize == 8) {
+                addI64(obj.getID(null));
+                addI64(0);
+                addI64(0);
+                addI64(0);
+            } else {
+                addI32((int)obj.getID(null));
+            }
+        } else {
+            if (RenderScript.sPointerSize == 8) {
+                addI64(0);
+                addI64(0);
+                addI64(0);
+                addI64(0);
+            } else {
+                addI32(0);
+            }
+        }
+    }
+
+    public void addF32(Float2 v) {
+        addF32(v.x);
+        addF32(v.y);
+    }
+    public void addF32(Float3 v) {
+        addF32(v.x);
+        addF32(v.y);
+        addF32(v.z);
+    }
+    public void addF32(Float4 v) {
+        addF32(v.x);
+        addF32(v.y);
+        addF32(v.z);
+        addF32(v.w);
+    }
+
+    public void addF64(Double2 v) {
+        addF64(v.x);
+        addF64(v.y);
+    }
+    public void addF64(Double3 v) {
+        addF64(v.x);
+        addF64(v.y);
+        addF64(v.z);
+    }
+    public void addF64(Double4 v) {
+        addF64(v.x);
+        addF64(v.y);
+        addF64(v.z);
+        addF64(v.w);
+    }
+
+    public void addI8(Byte2 v) {
+        addI8(v.x);
+        addI8(v.y);
+    }
+    public void addI8(Byte3 v) {
+        addI8(v.x);
+        addI8(v.y);
+        addI8(v.z);
+    }
+    public void addI8(Byte4 v) {
+        addI8(v.x);
+        addI8(v.y);
+        addI8(v.z);
+        addI8(v.w);
+    }
+
+    public void addU8(Short2 v) {
+        addU8(v.x);
+        addU8(v.y);
+    }
+    public void addU8(Short3 v) {
+        addU8(v.x);
+        addU8(v.y);
+        addU8(v.z);
+    }
+    public void addU8(Short4 v) {
+        addU8(v.x);
+        addU8(v.y);
+        addU8(v.z);
+        addU8(v.w);
+    }
+
+    public void addI16(Short2 v) {
+        addI16(v.x);
+        addI16(v.y);
+    }
+    public void addI16(Short3 v) {
+        addI16(v.x);
+        addI16(v.y);
+        addI16(v.z);
+    }
+    public void addI16(Short4 v) {
+        addI16(v.x);
+        addI16(v.y);
+        addI16(v.z);
+        addI16(v.w);
+    }
+
+    public void addU16(Int2 v) {
+        addU16(v.x);
+        addU16(v.y);
+    }
+    public void addU16(Int3 v) {
+        addU16(v.x);
+        addU16(v.y);
+        addU16(v.z);
+    }
+    public void addU16(Int4 v) {
+        addU16(v.x);
+        addU16(v.y);
+        addU16(v.z);
+        addU16(v.w);
+    }
+
+    public void addI32(Int2 v) {
+        addI32(v.x);
+        addI32(v.y);
+    }
+    public void addI32(Int3 v) {
+        addI32(v.x);
+        addI32(v.y);
+        addI32(v.z);
+    }
+    public void addI32(Int4 v) {
+        addI32(v.x);
+        addI32(v.y);
+        addI32(v.z);
+        addI32(v.w);
+    }
+
+    public void addU32(Long2 v) {
+        addU32(v.x);
+        addU32(v.y);
+    }
+    public void addU32(Long3 v) {
+        addU32(v.x);
+        addU32(v.y);
+        addU32(v.z);
+    }
+    public void addU32(Long4 v) {
+        addU32(v.x);
+        addU32(v.y);
+        addU32(v.z);
+        addU32(v.w);
+    }
+
+    public void addI64(Long2 v) {
+        addI64(v.x);
+        addI64(v.y);
+    }
+    public void addI64(Long3 v) {
+        addI64(v.x);
+        addI64(v.y);
+        addI64(v.z);
+    }
+    public void addI64(Long4 v) {
+        addI64(v.x);
+        addI64(v.y);
+        addI64(v.z);
+        addI64(v.w);
+    }
+
+    public void addU64(Long2 v) {
+        addU64(v.x);
+        addU64(v.y);
+    }
+    public void addU64(Long3 v) {
+        addU64(v.x);
+        addU64(v.y);
+        addU64(v.z);
+    }
+    public void addU64(Long4 v) {
+        addU64(v.x);
+        addU64(v.y);
+        addU64(v.z);
+        addU64(v.w);
+    }
+
+
+    public Float2 subFloat2() {
+        Float2 v = new Float2();
+        v.y = subF32();
+        v.x = subF32();
+        return v;
+    }
+    public Float3 subFloat3() {
+        Float3 v = new Float3();
+        v.z = subF32();
+        v.y = subF32();
+        v.x = subF32();
+        return v;
+    }
+    public Float4 subFloat4() {
+        Float4 v = new Float4();
+        v.w = subF32();
+        v.z = subF32();
+        v.y = subF32();
+        v.x = subF32();
+        return v;
+    }
+
+    public Double2 subDouble2() {
+        Double2 v = new Double2();
+        v.y = subF64();
+        v.x = subF64();
+        return v;
+    }
+    public Double3 subDouble3() {
+        Double3 v = new Double3();
+        v.z = subF64();
+        v.y = subF64();
+        v.x = subF64();
+        return v;
+    }
+    public Double4 subDouble4() {
+        Double4 v = new Double4();
+        v.w = subF64();
+        v.z = subF64();
+        v.y = subF64();
+        v.x = subF64();
+        return v;
+    }
+
+    public Byte2 subByte2() {
+        Byte2 v = new Byte2();
+        v.y = subI8();
+        v.x = subI8();
+        return v;
+    }
+    public Byte3 subByte3() {
+        Byte3 v = new Byte3();
+        v.z = subI8();
+        v.y = subI8();
+        v.x = subI8();
+        return v;
+    }
+    public Byte4 subByte4() {
+        Byte4 v = new Byte4();
+        v.w = subI8();
+        v.z = subI8();
+        v.y = subI8();
+        v.x = subI8();
+        return v;
+    }
+
+    public Short2 subShort2() {
+        Short2 v = new Short2();
+        v.y = subI16();
+        v.x = subI16();
+        return v;
+    }
+    public Short3 subShort3() {
+        Short3 v = new Short3();
+        v.z = subI16();
+        v.y = subI16();
+        v.x = subI16();
+        return v;
+    }
+    public Short4 subShort4() {
+        Short4 v = new Short4();
+        v.w = subI16();
+        v.z = subI16();
+        v.y = subI16();
+        v.x = subI16();
+        return v;
+    }
+
+    public Int2 subInt2() {
+        Int2 v = new Int2();
+        v.y = subI32();
+        v.x = subI32();
+        return v;
+    }
+    public Int3 subInt3() {
+        Int3 v = new Int3();
+        v.z = subI32();
+        v.y = subI32();
+        v.x = subI32();
+        return v;
+    }
+    public Int4 subInt4() {
+        Int4 v = new Int4();
+        v.w = subI32();
+        v.z = subI32();
+        v.y = subI32();
+        v.x = subI32();
+        return v;
+    }
+
+    public Long2 subLong2() {
+        Long2 v = new Long2();
+        v.y = subI64();
+        v.x = subI64();
+        return v;
+    }
+    public Long3 subLong3() {
+        Long3 v = new Long3();
+        v.z = subI64();
+        v.y = subI64();
+        v.x = subI64();
+        return v;
+    }
+    public Long4 subLong4() {
+        Long4 v = new Long4();
+        v.w = subI64();
+        v.z = subI64();
+        v.y = subI64();
+        v.x = subI64();
+        return v;
+    }
+
+
+
+    public void addMatrix(Matrix4f v) {
+        for (int i=0; i < v.mMat.length; i++) {
+            addF32(v.mMat[i]);
+        }
+    }
+
+    public Matrix4f subMatrix4f() {
+        Matrix4f v = new Matrix4f();
+        for (int i = v.mMat.length - 1; i >= 0; i--) {
+            v.mMat[i] = subF32();
+        }
+        return v;
+    }
+
+    public void addMatrix(Matrix3f v) {
+        for (int i=0; i < v.mMat.length; i++) {
+            addF32(v.mMat[i]);
+        }
+    }
+
+    public Matrix3f subMatrix3f() {
+        Matrix3f v = new Matrix3f();
+        for (int i = v.mMat.length - 1; i >= 0; i--) {
+            v.mMat[i] = subF32();
+        }
+        return v;
+    }
+
+    public void addMatrix(Matrix2f v) {
+        for (int i=0; i < v.mMat.length; i++) {
+            addF32(v.mMat[i]);
+        }
+    }
+
+    public Matrix2f subMatrix2f() {
+        Matrix2f v = new Matrix2f();
+        for (int i = v.mMat.length - 1; i >= 0; i--) {
+            v.mMat[i] = subF32();
+        }
+        return v;
+    }
+
+    public void addBoolean(boolean v) {
+        addI8((byte)(v ? 1 : 0));
+    }
+
+    public boolean subBoolean() {
+        byte v = subI8();
+        if (v == 1) {
+            return true;
+        }
+        return false;
+    }
+
+    public final byte[] getData() {
+        return mData;
+    }
+
+    /**
+     * Get the actual length used for the FieldPacker.
+     *
+     * @hide
+     */
+    public int getPos() {
+        return mPos;
+    }
+
+    private static void addToPack(FieldPacker fp, Object obj) {
+        if (obj instanceof Boolean) {
+            fp.addBoolean(((Boolean)obj).booleanValue());
+            return;
+        }
+
+        if (obj instanceof Byte) {
+            fp.addI8(((Byte)obj).byteValue());
+            return;
+        }
+
+        if (obj instanceof Short) {
+            fp.addI16(((Short)obj).shortValue());
+            return;
+        }
+
+        if (obj instanceof Integer) {
+            fp.addI32(((Integer)obj).intValue());
+            return;
+        }
+
+        if (obj instanceof Long) {
+            fp.addI64(((Long)obj).longValue());
+            return;
+        }
+
+        if (obj instanceof Float) {
+            fp.addF32(((Float)obj).floatValue());
+            return;
+        }
+
+        if (obj instanceof Double) {
+            fp.addF64(((Double)obj).doubleValue());
+            return;
+        }
+
+        if (obj instanceof Byte2) {
+            fp.addI8((Byte2)obj);
+            return;
+        }
+
+        if (obj instanceof Byte3) {
+            fp.addI8((Byte3)obj);
+            return;
+        }
+
+        if (obj instanceof Byte4) {
+            fp.addI8((Byte4)obj);
+            return;
+        }
+
+        if (obj instanceof Short2) {
+            fp.addI16((Short2)obj);
+            return;
+        }
+
+        if (obj instanceof Short3) {
+            fp.addI16((Short3)obj);
+            return;
+        }
+
+        if (obj instanceof Short4) {
+            fp.addI16((Short4)obj);
+            return;
+        }
+
+        if (obj instanceof Int2) {
+            fp.addI32((Int2)obj);
+            return;
+        }
+
+        if (obj instanceof Int3) {
+            fp.addI32((Int3)obj);
+            return;
+        }
+
+        if (obj instanceof Int4) {
+            fp.addI32((Int4)obj);
+            return;
+        }
+
+        if (obj instanceof Long2) {
+            fp.addI64((Long2)obj);
+            return;
+        }
+
+        if (obj instanceof Long3) {
+            fp.addI64((Long3)obj);
+            return;
+        }
+
+        if (obj instanceof Long4) {
+            fp.addI64((Long4)obj);
+            return;
+        }
+
+        if (obj instanceof Float2) {
+            fp.addF32((Float2)obj);
+            return;
+        }
+
+        if (obj instanceof Float3) {
+            fp.addF32((Float3)obj);
+            return;
+        }
+
+        if (obj instanceof Float4) {
+            fp.addF32((Float4)obj);
+            return;
+        }
+
+        if (obj instanceof Double2) {
+            fp.addF64((Double2)obj);
+            return;
+        }
+
+        if (obj instanceof Double3) {
+            fp.addF64((Double3)obj);
+            return;
+        }
+
+        if (obj instanceof Double4) {
+            fp.addF64((Double4)obj);
+            return;
+        }
+
+        if (obj instanceof Matrix2f) {
+            fp.addMatrix((Matrix2f)obj);
+            return;
+        }
+
+        if (obj instanceof Matrix3f) {
+            fp.addMatrix((Matrix3f)obj);
+            return;
+        }
+
+        if (obj instanceof Matrix4f) {
+            fp.addMatrix((Matrix4f)obj);
+            return;
+        }
+
+        if (obj instanceof BaseObj) {
+            fp.addObj((BaseObj)obj);
+            return;
+        }
+    }
+
+    private static int getPackedSize(Object obj) {
+        if (obj instanceof Boolean) {
+            return 1;
+        }
+
+        if (obj instanceof Byte) {
+            return 1;
+        }
+
+        if (obj instanceof Short) {
+            return 2;
+        }
+
+        if (obj instanceof Integer) {
+            return 4;
+        }
+
+        if (obj instanceof Long) {
+            return 8;
+        }
+
+        if (obj instanceof Float) {
+            return 4;
+        }
+
+        if (obj instanceof Double) {
+            return 8;
+        }
+
+        if (obj instanceof Byte2) {
+            return 2;
+        }
+
+        if (obj instanceof Byte3) {
+            return 3;
+        }
+
+        if (obj instanceof Byte4) {
+            return 4;
+        }
+
+        if (obj instanceof Short2) {
+            return 4;
+        }
+
+        if (obj instanceof Short3) {
+            return 6;
+        }
+
+        if (obj instanceof Short4) {
+            return 8;
+        }
+
+        if (obj instanceof Int2) {
+            return 8;
+        }
+
+        if (obj instanceof Int3) {
+            return 12;
+        }
+
+        if (obj instanceof Int4) {
+            return 16;
+        }
+
+        if (obj instanceof Long2) {
+            return 16;
+        }
+
+        if (obj instanceof Long3) {
+            return 24;
+        }
+
+        if (obj instanceof Long4) {
+            return 32;
+        }
+
+        if (obj instanceof Float2) {
+            return 8;
+        }
+
+        if (obj instanceof Float3) {
+            return 12;
+        }
+
+        if (obj instanceof Float4) {
+            return 16;
+        }
+
+        if (obj instanceof Double2) {
+            return 16;
+        }
+
+        if (obj instanceof Double3) {
+            return 24;
+        }
+
+        if (obj instanceof Double4) {
+            return 32;
+        }
+
+        if (obj instanceof Matrix2f) {
+            return 16;
+        }
+
+        if (obj instanceof Matrix3f) {
+            return 36;
+        }
+
+        if (obj instanceof Matrix4f) {
+            return 64;
+        }
+
+        if (obj instanceof BaseObj) {
+            if (RenderScript.sPointerSize == 8) {
+                return 32;
+            } else {
+                return 4;
+            }
+        }
+
+        return 0;
+    }
+
+    static FieldPacker createFieldPack(Object[] args) {
+        int len = 0;
+        for (Object arg : args) {
+            len += getPackedSize(arg);
+        }
+        FieldPacker fp = new FieldPacker(len);
+        for (Object arg : args) {
+            addToPack(fp, arg);
+        }
+        return fp;
+    }
+
+
+    private boolean resize(int newSize) {
+        if (newSize == mLen) {
+            return false;
+        }
+
+        byte[] newData = new byte[newSize];
+        System.arraycopy(mData, 0, newData, 0, mPos);
+        mData = newData;
+        mLen = newSize;
+        return true;
+    }
+
+    private void addSafely(Object obj) {
+        boolean retry;
+        final int oldPos = mPos;
+        do {
+            retry = false;
+            try {
+                addToPack(this, obj);
+            } catch (ArrayIndexOutOfBoundsException e) {
+                mPos = oldPos;
+                resize(mLen * 2);
+                retry = true;
+            }
+        } while (retry);
+    }
+
+    private byte mData[];
+    private int mPos;
+    private int mLen;
+    private BitSet mAlignment;
+}
diff --git a/androidx/renderscript/Float2.java b/androidx/renderscript/Float2.java
new file mode 100644
index 0000000..01a166b
--- /dev/null
+++ b/androidx/renderscript/Float2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript float2 type back to the Android system.
+ *
+ **/
+public class Float2 {
+    public Float2() {
+    }
+
+    public Float2(float initX, float initY) {
+        x = initX;
+        y = initY;
+    }
+
+    public float x;
+    public float y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Float3.java b/androidx/renderscript/Float3.java
new file mode 100644
index 0000000..bb7932a
--- /dev/null
+++ b/androidx/renderscript/Float3.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript float2 type back to the Android system.
+ *
+ **/
+public class Float3 {
+    public Float3() {
+    }
+    public Float3(float initX, float initY, float initZ) {
+        x = initX;
+        y = initY;
+        z = initZ;
+    }
+
+    public float x;
+    public float y;
+    public float z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Float4.java b/androidx/renderscript/Float4.java
new file mode 100644
index 0000000..8336d9e
--- /dev/null
+++ b/androidx/renderscript/Float4.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript float2 type back to the Android system.
+ *
+ **/
+public class Float4 {
+    public Float4() {
+    }
+
+    public Float4(float initX, float initY, float initZ, float initW) {
+        x = initX;
+        y = initY;
+        z = initZ;
+        w = initW;
+    }
+
+    public float x;
+    public float y;
+    public float z;
+    public float w;
+}
+
+
+
diff --git a/androidx/renderscript/Int2.java b/androidx/renderscript/Int2.java
new file mode 100644
index 0000000..fe86fe3
--- /dev/null
+++ b/androidx/renderscript/Int2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript int2 type back to the Android system.
+ *
+ **/
+public class Int2 {
+    public Int2() {
+    }
+
+    public Int2(int initX, int initY) {
+        x = initX;
+        y = initY;
+    }
+
+    public int x;
+    public int y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Int3.java b/androidx/renderscript/Int3.java
new file mode 100644
index 0000000..bd6fbc7
--- /dev/null
+++ b/androidx/renderscript/Int3.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript int3 type back to the Android system.
+ *
+ **/
+public class Int3 {
+    public Int3() {
+    }
+
+    public Int3(int initX, int initY, int initZ) {
+        x = initX;
+        y = initY;
+        z = initZ;
+    }
+
+    public int x;
+    public int y;
+    public int z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Int4.java b/androidx/renderscript/Int4.java
new file mode 100644
index 0000000..91e0b9f
--- /dev/null
+++ b/androidx/renderscript/Int4.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript int4 type back to the Android system.
+ *
+ **/
+public class Int4 {
+    public Int4() {
+    }
+
+    public Int4(int initX, int initY, int initZ, int initW) {
+        x = initX;
+        y = initY;
+        z = initZ;
+        w = initW;
+    }
+
+    public int x;
+    public int y;
+    public int z;
+    public int w;
+}
+
+
+
diff --git a/androidx/renderscript/Long2.java b/androidx/renderscript/Long2.java
new file mode 100644
index 0000000..0871706
--- /dev/null
+++ b/androidx/renderscript/Long2.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript long2 type back to the Android system.
+ **/
+public class Long2 {
+    public Long2() {
+    }
+
+    public Long2(long initX, long initY) {
+        x = initX;
+        y = initY;
+    }
+
+    public long x;
+    public long y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Long3.java b/androidx/renderscript/Long3.java
new file mode 100644
index 0000000..250b50f
--- /dev/null
+++ b/androidx/renderscript/Long3.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript long3 type back to the Android system.
+ **/
+public class Long3 {
+    public Long3() {
+    }
+
+    public Long3(long initX, long initY, long initZ) {
+        x = initX;
+        y = initY;
+        z = initZ;
+    }
+
+    public long x;
+    public long y;
+    public long z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Long4.java b/androidx/renderscript/Long4.java
new file mode 100644
index 0000000..438d34e
--- /dev/null
+++ b/androidx/renderscript/Long4.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript long4 type back to the Android system.
+ **/
+public class Long4 {
+    public Long4() {
+    }
+
+    public Long4(long initX, long initY, long initZ, long initW) {
+        x = initX;
+        y = initY;
+        z = initZ;
+        w = initW;
+    }
+
+    public long x;
+    public long y;
+    public long z;
+    public long w;
+}
+
+
+
diff --git a/androidx/renderscript/Matrix2f.java b/androidx/renderscript/Matrix2f.java
new file mode 100644
index 0000000..b5c5a08
--- /dev/null
+++ b/androidx/renderscript/Matrix2f.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2009-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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript rs_matrix2x2 type back to the Android system.
+ *
+ **/
+public class Matrix2f {
+
+    /**
+    * Creates a new identity 2x2 matrix
+    */
+    public Matrix2f() {
+        mMat = new float[4];
+        loadIdentity();
+    }
+
+    /**
+    * Creates a new matrix and sets its values from the given
+    * parameter
+    *
+    * @param dataArray values to set the matrix to, must be 4
+    *                  floats long
+    */
+    public Matrix2f(float[] dataArray) {
+        mMat = new float[4];
+        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+    }
+
+    /**
+    * Return a reference to the internal array representing matrix
+    * values. Modifying this array will also change the matrix
+    *
+    * @return internal array representing the matrix
+    */
+    public float[] getArray() {
+        return mMat;
+    }
+
+    /**
+    * Returns the value for a given row and column
+    *
+    * @param x column of the value to return
+    * @param y row of the value to return
+    *
+    * @return value in the yth row and xth column
+    */
+    public float get(int x, int y) {
+        return mMat[x*2 + y];
+    }
+
+    /**
+    * Sets the value for a given row and column
+    *
+    * @param x column of the value to set
+    * @param y row of the value to set
+    */
+    public void set(int x, int y, float v) {
+        mMat[x*2 + y] = v;
+    }
+
+    /**
+    * Sets the matrix values to identity
+    */
+    public void loadIdentity() {
+        mMat[0] = 1;
+        mMat[1] = 0;
+
+        mMat[2] = 0;
+        mMat[3] = 1;
+    }
+
+    /**
+    * Sets the values of the matrix to those of the parameter
+    *
+    * @param src matrix to load the values from
+    */
+    public void load(Matrix2f src) {
+        System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
+    }
+
+    /**
+    * Sets current values to be a rotation matrix of given angle
+    *
+    * @param rot rotation angle
+    */
+    public void loadRotate(float rot) {
+        float c, s;
+        rot *= (float)(java.lang.Math.PI / 180.0f);
+        c = (float)java.lang.Math.cos(rot);
+        s = (float)java.lang.Math.sin(rot);
+        mMat[0] = c;
+        mMat[1] = -s;
+        mMat[2] = s;
+        mMat[3] = c;
+    }
+
+    /**
+    * Sets current values to be a scale matrix of given dimensions
+    *
+    * @param x scale component x
+    * @param y scale component y
+    */
+    public void loadScale(float x, float y) {
+        loadIdentity();
+        mMat[0] = x;
+        mMat[3] = y;
+    }
+
+    /**
+    * Sets current values to be the result of multiplying two given
+    * matrices
+    *
+    * @param lhs left hand side matrix
+    * @param rhs right hand side matrix
+    */
+    public void loadMultiply(Matrix2f lhs, Matrix2f rhs) {
+        for (int i=0 ; i<2 ; i++) {
+            float ri0 = 0;
+            float ri1 = 0;
+            for (int j=0 ; j<2 ; j++) {
+                float rhs_ij = rhs.get(i,j);
+                ri0 += lhs.get(j,0) * rhs_ij;
+                ri1 += lhs.get(j,1) * rhs_ij;
+            }
+            set(i,0, ri0);
+            set(i,1, ri1);
+        }
+    }
+
+    /**
+    * Post-multiplies the current matrix by a given parameter
+    *
+    * @param rhs right hand side to multiply by
+    */
+    public void multiply(Matrix2f rhs) {
+        Matrix2f tmp = new Matrix2f();
+        tmp.loadMultiply(this, rhs);
+        load(tmp);
+    }
+    /**
+    * Modifies the current matrix by post-multiplying it with a
+    * rotation matrix of given angle
+    *
+    * @param rot angle of rotation
+    */
+    public void rotate(float rot) {
+        Matrix2f tmp = new Matrix2f();
+        tmp.loadRotate(rot);
+        multiply(tmp);
+    }
+    /**
+    * Modifies the current matrix by post-multiplying it with a
+    * scale matrix of given dimensions
+    *
+    * @param x scale component x
+    * @param y scale component y
+    */
+    public void scale(float x, float y) {
+        Matrix2f tmp = new Matrix2f();
+        tmp.loadScale(x, y);
+        multiply(tmp);
+    }
+    /**
+    * Sets the current matrix to its transpose
+    */
+    public void transpose() {
+        float temp = mMat[1];
+        mMat[1] = mMat[2];
+        mMat[2] = temp;
+    }
+
+    final float[] mMat;
+}
+
+
+
diff --git a/androidx/renderscript/Matrix3f.java b/androidx/renderscript/Matrix3f.java
new file mode 100644
index 0000000..699c42b
--- /dev/null
+++ b/androidx/renderscript/Matrix3f.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright (C) 2009-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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript rs_matrix3x3 type back to the Android system.
+ *
+ **/
+public class Matrix3f {
+
+    /**
+    * Creates a new identity 3x3 matrix
+    */
+    public Matrix3f() {
+        mMat = new float[9];
+        loadIdentity();
+    }
+
+    /**
+    * Creates a new matrix and sets its values from the given
+    * parameter
+    *
+    * @param dataArray values to set the matrix to, must be 9
+    *                  floats long
+    */
+    public Matrix3f(float[] dataArray) {
+        mMat = new float[9];
+        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+    }
+
+    /**
+    * Return a reference to the internal array representing matrix
+    * values. Modifying this array will also change the matrix
+    *
+    * @return internal array representing the matrix
+    */
+    public float[] getArray() {
+        return mMat;
+    }
+
+    /**
+    * Returns the value for a given row and column
+    *
+    * @param x column of the value to return
+    * @param y row of the value to return
+    *
+    * @return value in the yth row and xth column
+    */
+    public float get(int x, int y) {
+        return mMat[x*3 + y];
+    }
+
+    /**
+    * Sets the value for a given row and column
+    *
+    * @param x column of the value to set
+    * @param y row of the value to set
+    */
+    public void set(int x, int y, float v) {
+        mMat[x*3 + y] = v;
+    }
+
+    /**
+    * Sets the matrix values to identity
+    */
+    public void loadIdentity() {
+        mMat[0] = 1;
+        mMat[1] = 0;
+        mMat[2] = 0;
+
+        mMat[3] = 0;
+        mMat[4] = 1;
+        mMat[5] = 0;
+
+        mMat[6] = 0;
+        mMat[7] = 0;
+        mMat[8] = 1;
+    }
+
+    /**
+    * Sets the values of the matrix to those of the parameter
+    *
+    * @param src matrix to load the values from
+    */
+    public void load(Matrix3f src) {
+        System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
+    }
+
+    /**
+    * Sets current values to be a rotation matrix of certain angle
+    * about a given axis
+    *
+    * @param rot angle of rotation
+    * @param x rotation axis x
+    * @param y rotation axis y
+    * @param z rotation axis z
+    */
+    public void loadRotate(float rot, float x, float y, float z) {
+        float c, s;
+        rot *= (float)(java.lang.Math.PI / 180.0f);
+        c = (float)java.lang.Math.cos(rot);
+        s = (float)java.lang.Math.sin(rot);
+
+        float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
+        if (!(len != 1)) {
+            float recipLen = 1.f / len;
+            x *= recipLen;
+            y *= recipLen;
+            z *= recipLen;
+        }
+        float nc = 1.0f - c;
+        float xy = x * y;
+        float yz = y * z;
+        float zx = z * x;
+        float xs = x * s;
+        float ys = y * s;
+        float zs = z * s;
+        mMat[0] = x*x*nc +  c;
+        mMat[3] =  xy*nc - zs;
+        mMat[6] =  zx*nc + ys;
+        mMat[1] =  xy*nc + zs;
+        mMat[4] = y*y*nc +  c;
+        mMat[7] =  yz*nc - xs;
+        mMat[2] =  zx*nc - ys;
+        mMat[5] =  yz*nc + xs;
+        mMat[8] = z*z*nc +  c;
+    }
+
+    /**
+    * Makes the upper 2x2 a rotation matrix of the given angle
+    *
+    * @param rot rotation angle
+    */
+    public void loadRotate(float rot) {
+        loadIdentity();
+        float c, s;
+        rot *= (float)(java.lang.Math.PI / 180.0f);
+        c = (float)java.lang.Math.cos(rot);
+        s = (float)java.lang.Math.sin(rot);
+        mMat[0] = c;
+        mMat[1] = -s;
+        mMat[3] = s;
+        mMat[4] = c;
+    }
+
+    /**
+    * Makes the upper 2x2 a scale matrix of given dimensions
+    *
+    * @param x scale component x
+    * @param y scale component y
+    */
+    public void loadScale(float x, float y) {
+        loadIdentity();
+        mMat[0] = x;
+        mMat[4] = y;
+    }
+
+    /**
+    * Sets current values to be a scale matrix of given dimensions
+    *
+    * @param x scale component x
+    * @param y scale component y
+    * @param z scale component z
+    */
+    public void loadScale(float x, float y, float z) {
+        loadIdentity();
+        mMat[0] = x;
+        mMat[4] = y;
+        mMat[8] = z;
+    }
+
+    /**
+    * Sets current values to be a translation matrix of given
+    * dimensions
+    *
+    * @param x translation component x
+    * @param y translation component y
+    */
+    public void loadTranslate(float x, float y) {
+        loadIdentity();
+        mMat[6] = x;
+        mMat[7] = y;
+    }
+
+    /**
+    * Sets current values to be the result of multiplying two given
+    * matrices
+    *
+    * @param lhs left hand side matrix
+    * @param rhs right hand side matrix
+    */
+    public void loadMultiply(Matrix3f lhs, Matrix3f rhs) {
+        for (int i=0 ; i<3 ; i++) {
+            float ri0 = 0;
+            float ri1 = 0;
+            float ri2 = 0;
+            for (int j=0 ; j<3 ; j++) {
+                float rhs_ij = rhs.get(i,j);
+                ri0 += lhs.get(j,0) * rhs_ij;
+                ri1 += lhs.get(j,1) * rhs_ij;
+                ri2 += lhs.get(j,2) * rhs_ij;
+            }
+            set(i,0, ri0);
+            set(i,1, ri1);
+            set(i,2, ri2);
+        }
+    }
+
+    /**
+    * Post-multiplies the current matrix by a given parameter
+    *
+    * @param rhs right hand side to multiply by
+    */
+    public void multiply(Matrix3f rhs) {
+        Matrix3f tmp = new Matrix3f();
+        tmp.loadMultiply(this, rhs);
+        load(tmp);
+    }
+
+    /**
+    * Modifies the current matrix by post-multiplying it with a
+    * rotation matrix of certain angle about a given axis
+    *
+    * @param rot angle of rotation
+    * @param x rotation axis x
+    * @param y rotation axis y
+    * @param z rotation axis z
+    */
+    public void rotate(float rot, float x, float y, float z) {
+        Matrix3f tmp = new Matrix3f();
+        tmp.loadRotate(rot, x, y, z);
+        multiply(tmp);
+    }
+
+    /**
+    * Modifies the upper 2x2 of the current matrix by
+    * post-multiplying it with a rotation matrix of given angle
+    *
+    * @param rot angle of rotation
+    */
+    public void rotate(float rot) {
+        Matrix3f tmp = new Matrix3f();
+        tmp.loadRotate(rot);
+        multiply(tmp);
+    }
+
+    /**
+    * Modifies the upper 2x2 of the current matrix by
+    * post-multiplying it with a scale matrix of given dimensions
+    *
+    * @param x scale component x
+    * @param y scale component y
+    */
+    public void scale(float x, float y) {
+        Matrix3f tmp = new Matrix3f();
+        tmp.loadScale(x, y);
+        multiply(tmp);
+    }
+
+    /**
+    * Modifies the current matrix by post-multiplying it with a
+    * scale matrix of given dimensions
+    *
+    * @param x scale component x
+    * @param y scale component y
+    * @param z scale component z
+    */
+    public void scale(float x, float y, float z) {
+        Matrix3f tmp = new Matrix3f();
+        tmp.loadScale(x, y, z);
+        multiply(tmp);
+    }
+
+    /**
+    * Modifies the current matrix by post-multiplying it with a
+    * translation matrix of given dimensions
+    *
+    * @param x translation component x
+    * @param y translation component y
+    */
+    public void translate(float x, float y) {
+        Matrix3f tmp = new Matrix3f();
+        tmp.loadTranslate(x, y);
+        multiply(tmp);
+    }
+
+    /**
+    * Sets the current matrix to its transpose
+    */
+    public void transpose() {
+        for(int i = 0; i < 2; ++i) {
+            for(int j = i + 1; j < 3; ++j) {
+                float temp = mMat[i*3 + j];
+                mMat[i*3 + j] = mMat[j*3 + i];
+                mMat[j*3 + i] = temp;
+            }
+        }
+    }
+
+    final float[] mMat;
+}
+
+
diff --git a/androidx/renderscript/Matrix4f.java b/androidx/renderscript/Matrix4f.java
new file mode 100644
index 0000000..6a38af8
--- /dev/null
+++ b/androidx/renderscript/Matrix4f.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2009-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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript rs_matrix4x4 type back to the Android system.
+ *
+ **/
+public class Matrix4f {
+
+    /**
+    * Creates a new identity 4x4 matrix
+    */
+    public Matrix4f() {
+        mMat = new float[16];
+        loadIdentity();
+    }
+
+    /**
+    * Creates a new matrix and sets its values from the given
+    * parameter
+    *
+    * @param dataArray values to set the matrix to, must be 16
+    *                  floats long
+    */
+    public Matrix4f(float[] dataArray) {
+        mMat = new float[16];
+        System.arraycopy(dataArray, 0, mMat, 0, mMat.length);
+    }
+
+    /**
+    * Return a reference to the internal array representing matrix
+    * values. Modifying this array will also change the matrix
+    *
+    * @return internal array representing the matrix
+    */
+    public float[] getArray() {
+        return mMat;
+    }
+
+    /**
+    * Returns the value for a given row and column
+    *
+    * @param x column of the value to return
+    * @param y row of the value to return
+    *
+    * @return value in the yth row and xth column
+    */
+    public float get(int x, int y) {
+        return mMat[x*4 + y];
+    }
+
+    /**
+    * Sets the value for a given row and column
+    *
+    * @param x column of the value to set
+    * @param y row of the value to set
+    */
+    public void set(int x, int y, float v) {
+        mMat[x*4 + y] = v;
+    }
+
+    /**
+    * Sets the matrix values to identity
+    */
+    public void loadIdentity() {
+        mMat[0] = 1;
+        mMat[1] = 0;
+        mMat[2] = 0;
+        mMat[3] = 0;
+
+        mMat[4] = 0;
+        mMat[5] = 1;
+        mMat[6] = 0;
+        mMat[7] = 0;
+
+        mMat[8] = 0;
+        mMat[9] = 0;
+        mMat[10] = 1;
+        mMat[11] = 0;
+
+        mMat[12] = 0;
+        mMat[13] = 0;
+        mMat[14] = 0;
+        mMat[15] = 1;
+    }
+
+    /**
+    * Sets the values of the matrix to those of the parameter
+    *
+    * @param src matrix to load the values from
+    */
+    public void load(Matrix4f src) {
+        System.arraycopy(src.getArray(), 0, mMat, 0, mMat.length);
+    }
+
+    /**
+    * Sets the values of the matrix to those of the parameter
+    *
+    * @param src matrix to load the values from
+    * @hide
+    */
+    public void load(Matrix3f src) {
+        mMat[0] = src.mMat[0];
+        mMat[1] = src.mMat[1];
+        mMat[2] = src.mMat[2];
+        mMat[3] = 0;
+
+        mMat[4] = src.mMat[3];
+        mMat[5] = src.mMat[4];
+        mMat[6] = src.mMat[5];
+        mMat[7] = 0;
+
+        mMat[8] = src.mMat[6];
+        mMat[9] = src.mMat[7];
+        mMat[10] = src.mMat[8];
+        mMat[11] = 0;
+
+        mMat[12] = 0;
+        mMat[13] = 0;
+        mMat[14] = 0;
+        mMat[15] = 1;
+    }
+
+    /**
+    * Sets current values to be a rotation matrix of certain angle
+    * about a given axis
+    *
+    * @param rot angle of rotation
+    * @param x rotation axis x
+    * @param y rotation axis y
+    * @param z rotation axis z
+    */
+    public void loadRotate(float rot, float x, float y, float z) {
+        float c, s;
+        mMat[3] = 0;
+        mMat[7] = 0;
+        mMat[11]= 0;
+        mMat[12]= 0;
+        mMat[13]= 0;
+        mMat[14]= 0;
+        mMat[15]= 1;
+        rot *= (float)(java.lang.Math.PI / 180.0f);
+        c = (float)java.lang.Math.cos(rot);
+        s = (float)java.lang.Math.sin(rot);
+
+        float len = (float)java.lang.Math.sqrt(x*x + y*y + z*z);
+        if (!(len != 1)) {
+            float recipLen = 1.f / len;
+            x *= recipLen;
+            y *= recipLen;
+            z *= recipLen;
+        }
+        float nc = 1.0f - c;
+        float xy = x * y;
+        float yz = y * z;
+        float zx = z * x;
+        float xs = x * s;
+        float ys = y * s;
+        float zs = z * s;
+        mMat[ 0] = x*x*nc +  c;
+        mMat[ 4] =  xy*nc - zs;
+        mMat[ 8] =  zx*nc + ys;
+        mMat[ 1] =  xy*nc + zs;
+        mMat[ 5] = y*y*nc +  c;
+        mMat[ 9] =  yz*nc - xs;
+        mMat[ 2] =  zx*nc - ys;
+        mMat[ 6] =  yz*nc + xs;
+        mMat[10] = z*z*nc +  c;
+    }
+
+    /**
+    * Sets current values to be a scale matrix of given dimensions
+    *
+    * @param x scale component x
+    * @param y scale component y
+    * @param z scale component z
+    */
+    public void loadScale(float x, float y, float z) {
+        loadIdentity();
+        mMat[0] = x;
+        mMat[5] = y;
+        mMat[10] = z;
+    }
+
+    /**
+    * Sets current values to be a translation matrix of given
+    * dimensions
+    *
+    * @param x translation component x
+    * @param y translation component y
+    * @param z translation component z
+    */
+    public void loadTranslate(float x, float y, float z) {
+        loadIdentity();
+        mMat[12] = x;
+        mMat[13] = y;
+        mMat[14] = z;
+    }
+
+    /**
+    * Sets current values to be the result of multiplying two given
+    * matrices
+    *
+    * @param lhs left hand side matrix
+    * @param rhs right hand side matrix
+    */
+    public void loadMultiply(Matrix4f lhs, Matrix4f rhs) {
+        for (int i=0 ; i<4 ; i++) {
+            float ri0 = 0;
+            float ri1 = 0;
+            float ri2 = 0;
+            float ri3 = 0;
+            for (int j=0 ; j<4 ; j++) {
+                float rhs_ij = rhs.get(i,j);
+                ri0 += lhs.get(j,0) * rhs_ij;
+                ri1 += lhs.get(j,1) * rhs_ij;
+                ri2 += lhs.get(j,2) * rhs_ij;
+                ri3 += lhs.get(j,3) * rhs_ij;
+            }
+            set(i,0, ri0);
+            set(i,1, ri1);
+            set(i,2, ri2);
+            set(i,3, ri3);
+        }
+    }
+
+    /**
+    * Set current values to be an orthographic projection matrix
+    *
+    * @param l location of the left vertical clipping plane
+    * @param r location of the right vertical clipping plane
+    * @param b location of the bottom horizontal clipping plane
+    * @param t location of the top horizontal clipping plane
+    * @param n location of the near clipping plane
+    * @param f location of the far clipping plane
+    */
+    public void loadOrtho(float l, float r, float b, float t, float n, float f) {
+        loadIdentity();
+        mMat[0] = 2 / (r - l);
+        mMat[5] = 2 / (t - b);
+        mMat[10]= -2 / (f - n);
+        mMat[12]= -(r + l) / (r - l);
+        mMat[13]= -(t + b) / (t - b);
+        mMat[14]= -(f + n) / (f - n);
+    }
+
+    /**
+    * Set current values to be an orthographic projection matrix
+    * with the right and bottom clipping planes set to the given
+    * values. Left and top clipping planes are set to 0. Near and
+    * far are set to -1, 1 respectively
+    *
+    * @param w location of the right vertical clipping plane
+    * @param h location of the bottom horizontal clipping plane
+    *
+    */
+    public void loadOrthoWindow(int w, int h) {
+        loadOrtho(0,w, h,0, -1,1);
+    }
+
+    /**
+    * Sets current values to be a perspective projection matrix
+    *
+    * @param l location of the left vertical clipping plane
+    * @param r location of the right vertical clipping plane
+    * @param b location of the bottom horizontal clipping plane
+    * @param t location of the top horizontal clipping plane
+    * @param n location of the near clipping plane, must be positive
+    * @param f location of the far clipping plane, must be positive
+    *
+    */
+    public void loadFrustum(float l, float r, float b, float t, float n, float f) {
+        loadIdentity();
+        mMat[0] = 2 * n / (r - l);
+        mMat[5] = 2 * n / (t - b);
+        mMat[8] = (r + l) / (r - l);
+        mMat[9] = (t + b) / (t - b);
+        mMat[10]= -(f + n) / (f - n);
+        mMat[11]= -1;
+        mMat[14]= -2*f*n / (f - n);
+        mMat[15]= 0;
+    }
+
+    /**
+    * Sets current values to be a perspective projection matrix
+    *
+    * @param fovy vertical field of view angle in degrees
+    * @param aspect aspect ratio of the screen
+    * @param near near cliping plane, must be positive
+    * @param far far clipping plane, must be positive
+    */
+    public void loadPerspective(float fovy, float aspect, float near, float far) {
+        float top = near * (float)Math.tan((float) (fovy * Math.PI / 360.0f));
+        float bottom = -top;
+        float left = bottom * aspect;
+        float right = top * aspect;
+        loadFrustum(left, right, bottom, top, near, far);
+    }
+
+    /**
+    * Helper function to set the current values to a perspective
+    * projection matrix with aspect ratio defined by the parameters
+    * and (near, far), (bottom, top) mapping to (-1, 1) at z = 0
+    *
+    * @param w screen width
+    * @param h screen height
+    */
+    public void loadProjectionNormalized(int w, int h) {
+        // range -1,1 in the narrow axis at z = 0.
+        Matrix4f m1 = new Matrix4f();
+        Matrix4f m2 = new Matrix4f();
+
+        if(w > h) {
+            float aspect = ((float)w) / h;
+            m1.loadFrustum(-aspect,aspect,  -1,1,  1,100);
+        } else {
+            float aspect = ((float)h) / w;
+            m1.loadFrustum(-1,1, -aspect,aspect, 1,100);
+        }
+
+        m2.loadRotate(180, 0, 1, 0);
+        m1.loadMultiply(m1, m2);
+
+        m2.loadScale(-2, 2, 1);
+        m1.loadMultiply(m1, m2);
+
+        m2.loadTranslate(0, 0, 2);
+        m1.loadMultiply(m1, m2);
+
+        load(m1);
+    }
+
+    /**
+    * Post-multiplies the current matrix by a given parameter
+    *
+    * @param rhs right hand side to multiply by
+    */
+    public void multiply(Matrix4f rhs) {
+        Matrix4f tmp = new Matrix4f();
+        tmp.loadMultiply(this, rhs);
+        load(tmp);
+    }
+    /**
+    * Modifies the current matrix by post-multiplying it with a
+    * rotation matrix of certain angle about a given axis
+    *
+    * @param rot angle of rotation
+    * @param x rotation axis x
+    * @param y rotation axis y
+    * @param z rotation axis z
+    */
+    public void rotate(float rot, float x, float y, float z) {
+        Matrix4f tmp = new Matrix4f();
+        tmp.loadRotate(rot, x, y, z);
+        multiply(tmp);
+    }
+
+    /**
+    * Modifies the current matrix by post-multiplying it with a
+    * scale matrix of given dimensions
+    *
+    * @param x scale component x
+    * @param y scale component y
+    * @param z scale component z
+    */
+    public void scale(float x, float y, float z) {
+        Matrix4f tmp = new Matrix4f();
+        tmp.loadScale(x, y, z);
+        multiply(tmp);
+    }
+
+    /**
+    * Modifies the current matrix by post-multiplying it with a
+    * translation matrix of given dimensions
+    *
+    * @param x translation component x
+    * @param y translation component y
+    * @param z translation component z
+    */
+    public void translate(float x, float y, float z) {
+        Matrix4f tmp = new Matrix4f();
+        tmp.loadTranslate(x, y, z);
+        multiply(tmp);
+    }
+    private float computeCofactor(int i, int j) {
+        int c0 = (i+1) % 4;
+        int c1 = (i+2) % 4;
+        int c2 = (i+3) % 4;
+        int r0 = (j+1) % 4;
+        int r1 = (j+2) % 4;
+        int r2 = (j+3) % 4;
+
+        float minor = (mMat[c0 + 4*r0] * (mMat[c1 + 4*r1] * mMat[c2 + 4*r2] -
+                                            mMat[c1 + 4*r2] * mMat[c2 + 4*r1]))
+                     - (mMat[c0 + 4*r1] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r2] -
+                                            mMat[c1 + 4*r2] * mMat[c2 + 4*r0]))
+                     + (mMat[c0 + 4*r2] * (mMat[c1 + 4*r0] * mMat[c2 + 4*r1] -
+                                            mMat[c1 + 4*r1] * mMat[c2 + 4*r0]));
+
+        float cofactor = ((i+j) & 1) != 0 ? -minor : minor;
+        return cofactor;
+    }
+
+    /**
+    * Sets the current matrix to its inverse
+    */
+    public boolean inverse() {
+
+        Matrix4f result = new Matrix4f();
+
+        for (int i = 0; i < 4; ++i) {
+            for (int j = 0; j < 4; ++j) {
+                result.mMat[4*i + j] = computeCofactor(i, j);
+            }
+        }
+
+        // Dot product of 0th column of source and 0th row of result
+        float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[1] +
+                     mMat[8]*result.mMat[2] + mMat[12]*result.mMat[3];
+
+        if (Math.abs(det) < 1e-6) {
+            return false;
+        }
+
+        det = 1.0f / det;
+        for (int i = 0; i < 16; ++i) {
+            mMat[i] = result.mMat[i] * det;
+        }
+
+        return true;
+    }
+
+    /**
+    * Sets the current matrix to its inverse transpose
+    */
+    public boolean inverseTranspose() {
+
+        Matrix4f result = new Matrix4f();
+
+        for (int i = 0; i < 4; ++i) {
+            for (int j = 0; j < 4; ++j) {
+                result.mMat[4*j + i] = computeCofactor(i, j);
+            }
+        }
+
+        float det = mMat[0]*result.mMat[0] + mMat[4]*result.mMat[4] +
+                     mMat[8]*result.mMat[8] + mMat[12]*result.mMat[12];
+
+        if (Math.abs(det) < 1e-6) {
+            return false;
+        }
+
+        det = 1.0f / det;
+        for (int i = 0; i < 16; ++i) {
+            mMat[i] = result.mMat[i] * det;
+        }
+
+        return true;
+    }
+
+    /**
+    * Sets the current matrix to its transpose
+    */
+    public void transpose() {
+        for(int i = 0; i < 3; ++i) {
+            for(int j = i + 1; j < 4; ++j) {
+                float temp = mMat[i*4 + j];
+                mMat[i*4 + j] = mMat[j*4 + i];
+                mMat[j*4 + i] = temp;
+            }
+        }
+    }
+
+    final float[] mMat;
+}
diff --git a/androidx/renderscript/RSDriverException.java b/androidx/renderscript/RSDriverException.java
new file mode 100644
index 0000000..11b5be2
--- /dev/null
+++ b/androidx/renderscript/RSDriverException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 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 androidx.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * RenderScript
+ */
+public class RSDriverException extends RSRuntimeException {
+    public RSDriverException(String string) {
+        super(string);
+    }
+}
+
+
+
diff --git a/androidx/renderscript/RSIllegalArgumentException.java b/androidx/renderscript/RSIllegalArgumentException.java
new file mode 100644
index 0000000..6e7c0e9
--- /dev/null
+++ b/androidx/renderscript/RSIllegalArgumentException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 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 androidx.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * RenderScript
+ */
+public class RSIllegalArgumentException extends RSRuntimeException {
+    public RSIllegalArgumentException(String string) {
+        super(string);
+    }
+}
+
+
diff --git a/androidx/renderscript/RSInvalidStateException.java b/androidx/renderscript/RSInvalidStateException.java
new file mode 100644
index 0000000..82cc7c9
--- /dev/null
+++ b/androidx/renderscript/RSInvalidStateException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 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 androidx.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * RenderScript
+ */
+public class RSInvalidStateException extends RSRuntimeException {
+    public RSInvalidStateException(String string) {
+        super(string);
+    }
+}
+
+
+
diff --git a/androidx/renderscript/RSRuntimeException.java b/androidx/renderscript/RSRuntimeException.java
new file mode 100644
index 0000000..886cd14
--- /dev/null
+++ b/androidx/renderscript/RSRuntimeException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2010 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 androidx.renderscript;
+
+
+/**
+ * Base class for all exceptions thrown by the Android
+ * RenderScript
+ */
+public class RSRuntimeException
+  extends java.lang.RuntimeException {
+    public RSRuntimeException(String string) {
+        super(string);
+    }
+}
+
diff --git a/androidx/renderscript/RenderScript.java b/androidx/renderscript/RenderScript.java
new file mode 100644
index 0000000..cf80342
--- /dev/null
+++ b/androidx/renderscript/RenderScript.java
@@ -0,0 +1,1748 @@
+/*
+ * Copyright (C) 2013 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 androidx.renderscript;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+import java.util.ArrayList;
+import java.nio.ByteBuffer;
+
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Process;
+import android.util.Log;
+import android.view.Surface;
+
+/**
+ * This class provides access to a RenderScript context, which controls RenderScript
+ * initialization, resource management, and teardown. An instance of the RenderScript
+ * class must be created before any other RS objects can be created.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating an application that uses RenderScript, read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a> developer guide.</p>
+ * </div>
+ **/
+public class RenderScript {
+    static final String LOG_TAG = "RenderScript_jni";
+    static final boolean DEBUG  = false;
+    @SuppressWarnings({"UnusedDeclaration", "deprecation"})
+    static final boolean LOG_ENABLED = false;
+    static final int SUPPORT_LIB_API = 23;
+    static final int SUPPORT_LIB_VERSION = 2301;
+
+    static private ArrayList<RenderScript> mProcessContextList = new ArrayList<RenderScript>();
+    private boolean mIsProcessContext = false;
+    private boolean mEnableMultiInput = false;
+    private int mDispatchAPILevel = 0;
+
+    private int mContextFlags = 0;
+    private int mContextSdkVersion = 0;
+
+    private Context mApplicationContext;
+    private String mNativeLibDir;
+
+    static private String mBlackList = "";
+     /**
+     * Sets the blackList of Models to only use support lib runtime.
+     * Should be used before context create.
+     *
+     * @param blackList User provided black list string.
+     *
+     * Format: "(MANUFACTURER1:PRODUCT1:MODEL1), (MANUFACTURER2:PRODUCT2:MODEL2)..."
+     * e.g. : To Blacklist Nexus 7(2013) and Nexus 5.
+     *        mBlackList = "(asus:razor:Nexus 7), (LGE:hammerhead:Nexus 5)";
+     */
+    static public void setBlackList(String blackList) {
+        if (blackList != null) {
+            mBlackList = blackList;
+        }
+    }
+     /**
+     * Force using support lib runtime.
+     * Should be used before context create.
+     *
+     */
+    static public void forceCompat() {
+        sNative = 0;
+    }
+    /*
+     * We use a class initializer to allow the native code to cache some
+     * field offsets.
+     */
+    @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"})
+    static boolean sInitialized;
+    static boolean sUseGCHooks;
+    static Object sRuntime;
+    static Method registerNativeAllocation;
+    static Method registerNativeFree;
+
+    static Object lock = new Object();
+
+    // Non-threadsafe functions.
+    native boolean nLoadSO(boolean useNative, int deviceApi, String libPath);
+    native boolean nLoadIOSO();
+    native long nDeviceCreate();
+    native void nDeviceDestroy(long dev);
+    native void nDeviceSetConfig(long dev, int param, int value);
+    native int nContextGetUserMessage(long con, int[] data);
+    native String nContextGetErrorMessage(long con);
+    native int  nContextPeekMessage(long con, int[] subID);
+    native void nContextInitToClient(long con);
+    native void nContextDeinitToClient(long con);
+
+    static private int sNative = -1;
+    static private int sSdkVersion = -1;
+    static private boolean useIOlib = false;
+    static private boolean useNative;
+
+    /*
+     * Context creation flag that specifies a normal context.
+     * RenderScript Support lib only support normal context.
+     */
+    public static final int CREATE_FLAG_NONE = 0x0000;
+
+    int getDispatchAPILevel() {
+        return mDispatchAPILevel;
+    }
+
+    boolean isUseNative() {
+        return useNative;
+    }
+    /*
+     * Detect the bitness of the VM to allow FieldPacker and generated code to do the right thing.
+     */
+    static native int rsnSystemGetPointerSize();
+    static int sPointerSize;
+    static public int getPointerSize() {
+        // We provide an accessor rather than making the data item public for two reasons.
+        // 1) Prevents anyone outside this class from writing the data item.
+        // 2) Prevents anyone outside this class from reading the data item unless a class
+        //    instance has been created (ensuring the data item has been initialized).
+        // DISCLAIMER: Reflection can circumvent these preventive measures.
+        synchronized(lock) {
+            if (!sInitialized)
+                throw new RSInvalidStateException("Calling getPointerSize() before any RenderScript instantiated");
+        }
+        return sPointerSize;
+    }
+
+    /**
+     * Determines whether or not we should be thunking into the native
+     * RenderScript layer or actually using the compatibility library.
+     */
+    static private boolean setupNative(int sdkVersion, Context ctx) {
+        // if targetSdkVersion is higher than the device api version, always use compat mode.
+        // Workaround for KK
+        if (android.os.Build.VERSION.SDK_INT < sdkVersion &&
+            android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
+            sNative = 0;
+        }
+
+        if (sNative == -1) {
+
+            // get the value of the debug.rs.forcecompat property
+            int forcecompat = 0;
+            try {
+                Class<?> sysprop = Class.forName("android.os.SystemProperties");
+                Class[] signature = {String.class, Integer.TYPE};
+                Method getint = sysprop.getDeclaredMethod("getInt", signature);
+                Object[] args = {"debug.rs.forcecompat", new Integer(0)};
+                forcecompat = ((java.lang.Integer)getint.invoke(null, args)).intValue();
+            } catch (Exception e) {
+
+            }
+
+            if ((android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT)
+                     && forcecompat == 0) {
+                sNative = 1;
+            } else {
+                sNative = 0;
+            }
+
+
+            if (sNative == 1) {
+                // Workarounds that may disable thunking go here
+                ApplicationInfo info;
+                try {
+                    info = ctx.getPackageManager().getApplicationInfo(ctx.getPackageName(),
+                                                                      PackageManager.GET_META_DATA);
+                } catch (PackageManager.NameNotFoundException e) {
+                    // assume no workarounds needed
+                    return true;
+                }
+                long minorVersion = 0;
+
+                // load minorID from reflection
+                try {
+                    Class<?> javaRS = Class.forName("android.renderscript.RenderScript");
+                    Method getMinorID = javaRS.getDeclaredMethod("getMinorID");
+                    minorVersion = ((java.lang.Long)getMinorID.invoke(null)).longValue();
+                } catch (Exception e) {
+                    // minor version remains 0 on devices with no possible WARs
+                }
+
+                if (info.metaData != null) {
+                    // asynchronous teardown: minor version 1+
+                    if (info.metaData.getBoolean("androidx.renderscript.EnableAsyncTeardown") == true) {
+                        if (minorVersion == 0) {
+                            sNative = 0;
+                        }
+                    }
+
+                    // blur issues on some drivers with 4.4
+                    if (info.metaData.getBoolean("androidx.renderscript.EnableBlurWorkaround") == true) {
+                        if (android.os.Build.VERSION.SDK_INT <= 19) {
+                            //android.util.Log.e("rs", "war on");
+                            sNative = 0;
+                        }
+                    }
+                }
+                // end of workarounds
+            }
+        }
+
+        if (sNative == 1) {
+            // check against the blacklist
+            if (mBlackList.length() > 0) {
+                String deviceInfo = '(' +
+                                    android.os.Build.MANUFACTURER +
+                                    ':' +
+                                    android.os.Build.PRODUCT +
+                                    ':' +
+                                    android.os.Build.MODEL +
+                                    ')';
+                if (mBlackList.contains(deviceInfo)) {
+                    sNative = 0;
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Name of the file that holds the object cache.
+     */
+    private static final String CACHE_PATH = "com.android.renderscript.cache";
+    static String mCachePath;
+
+     /**
+     * Sets the directory to use as a persistent storage for the
+     * renderscript object file cache.
+     *
+     * @hide
+     * @param cacheDir A directory the current process can write to
+     */
+    public static void setupDiskCache(File cacheDir) {
+        File f = new File(cacheDir, CACHE_PATH);
+        mCachePath = f.getAbsolutePath();
+        f.mkdirs();
+    }
+
+    /**
+     * ContextType specifies the specific type of context to be created.
+     *
+     */
+    public enum ContextType {
+        /**
+         * NORMAL context, this is the default and what shipping apps should
+         * use.
+         */
+        NORMAL (0),
+
+        /**
+         * DEBUG context, perform extra runtime checks to validate the
+         * kernels and APIs are being used as intended.  Get and SetElementAt
+         * will be bounds checked in this mode.
+         */
+        DEBUG (1),
+
+        /**
+         * PROFILE context, Intended to be used once the first time an
+         * application is run on a new device.  This mode allows the runtime to
+         * do additional testing and performance tuning.
+         */
+        PROFILE (2);
+
+        int mID;
+        ContextType(int id) {
+            mID = id;
+        }
+    }
+
+    ContextType mContextType;
+    // Methods below are wrapped to protect the non-threadsafe
+    // lockless fifo.
+
+    native long  rsnContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir);
+    synchronized long nContextCreate(long dev, int ver, int sdkVer, int contextType, String nativeLibDir) {
+        return rsnContextCreate(dev, ver, sdkVer, contextType, nativeLibDir);
+    }
+    native void rsnContextDestroy(long con);
+    synchronized void nContextDestroy() {
+        validate();
+
+        // take teardown lock
+        // teardown lock can only be taken when no objects are being destroyed
+        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
+        wlock.lock();
+
+        long curCon = mContext;
+        // context is considered dead as of this point
+        mContext = 0;
+
+        wlock.unlock();
+        rsnContextDestroy(curCon);
+    }
+    native void rsnContextSetPriority(long con, int p);
+    synchronized void nContextSetPriority(int p) {
+        validate();
+        rsnContextSetPriority(mContext, p);
+    }
+    native void rsnContextDump(long con, int bits);
+    synchronized void nContextDump(int bits) {
+        validate();
+        rsnContextDump(mContext, bits);
+    }
+    native void rsnContextFinish(long con);
+    synchronized void nContextFinish() {
+        validate();
+        rsnContextFinish(mContext);
+    }
+
+    native void rsnContextSendMessage(long con, int id, int[] data);
+    synchronized void nContextSendMessage(int id, int[] data) {
+        validate();
+        rsnContextSendMessage(mContext, id, data);
+    }
+
+    // nObjDestroy is explicitly _not_ synchronous to prevent crashes in finalizers
+    native void rsnObjDestroy(long con, long id);
+    void nObjDestroy(long id) {
+        // There is a race condition here.  The calling code may be run
+        // by the gc while teardown is occuring.  This protects againts
+        // deleting dead objects.
+        if (mContext != 0) {
+            rsnObjDestroy(mContext, id);
+        }
+    }
+
+    native long  rsnElementCreate(long con, long type, int kind, boolean norm, int vecSize);
+    synchronized long nElementCreate(long type, int kind, boolean norm, int vecSize) {
+        validate();
+        return rsnElementCreate(mContext, type, kind, norm, vecSize);
+    }
+    native long  rsnElementCreate2(long con, long[] elements, String[] names, int[] arraySizes);
+    synchronized long nElementCreate2(long[] elements, String[] names, int[] arraySizes) {
+        validate();
+        return rsnElementCreate2(mContext, elements, names, arraySizes);
+    }
+    native void rsnElementGetNativeData(long con, long id, int[] elementData);
+    synchronized void nElementGetNativeData(long id, int[] elementData) {
+        validate();
+        rsnElementGetNativeData(mContext, id, elementData);
+    }
+    native void rsnElementGetSubElements(long con, long id,
+                                         long[] IDs, String[] names, int[] arraySizes);
+    synchronized void nElementGetSubElements(long id, long[] IDs, String[] names, int[] arraySizes) {
+        validate();
+        rsnElementGetSubElements(mContext, id, IDs, names, arraySizes);
+    }
+
+    native long rsnTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
+    synchronized long nTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
+        validate();
+        return rsnTypeCreate(mContext, eid, x, y, z, mips, faces, yuv);
+    }
+
+    native void rsnTypeGetNativeData(long con, long id, long[] typeData);
+    synchronized void nTypeGetNativeData(long id, long[] typeData) {
+        validate();
+        rsnTypeGetNativeData(mContext, id, typeData);
+    }
+
+    native long  rsnAllocationCreateTyped(long con, long type, int mip, int usage, long pointer);
+    synchronized long nAllocationCreateTyped(long type, int mip, int usage, long pointer) {
+        validate();
+        return rsnAllocationCreateTyped(mContext, type, mip, usage, pointer);
+    }
+    native long  rsnAllocationCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
+    synchronized long nAllocationCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
+        validate();
+        return rsnAllocationCreateFromBitmap(mContext, type, mip, bmp, usage);
+    }
+
+    native long  rsnAllocationCreateBitmapBackedAllocation(long con, long type, int mip, Bitmap bmp, int usage);
+    synchronized long nAllocationCreateBitmapBackedAllocation(long type, int mip, Bitmap bmp, int usage) {
+        validate();
+        return rsnAllocationCreateBitmapBackedAllocation(mContext, type, mip, bmp, usage);
+    }
+
+
+    native long  rsnAllocationCubeCreateFromBitmap(long con, long type, int mip, Bitmap bmp, int usage);
+    synchronized long nAllocationCubeCreateFromBitmap(long type, int mip, Bitmap bmp, int usage) {
+        validate();
+        return rsnAllocationCubeCreateFromBitmap(mContext, type, mip, bmp, usage);
+    }
+    native long  rsnAllocationCreateBitmapRef(long con, long type, Bitmap bmp);
+    synchronized long nAllocationCreateBitmapRef(long type, Bitmap bmp) {
+        validate();
+        return rsnAllocationCreateBitmapRef(mContext, type, bmp);
+    }
+    native long  rsnAllocationCreateFromAssetStream(long con, int mips, int assetStream, int usage);
+    synchronized long nAllocationCreateFromAssetStream(int mips, int assetStream, int usage) {
+        validate();
+        return rsnAllocationCreateFromAssetStream(mContext, mips, assetStream, usage);
+    }
+
+    native void  rsnAllocationCopyToBitmap(long con, long alloc, Bitmap bmp);
+    synchronized void nAllocationCopyToBitmap(long alloc, Bitmap bmp) {
+        validate();
+        rsnAllocationCopyToBitmap(mContext, alloc, bmp);
+    }
+
+
+    native void rsnAllocationSyncAll(long con, long alloc, int src);
+    synchronized void nAllocationSyncAll(long alloc, int src) {
+        validate();
+        rsnAllocationSyncAll(mContext, alloc, src);
+    }
+
+    native void rsnAllocationSetSurface(long con, long alloc, Surface sur);
+    synchronized void nAllocationSetSurface(long alloc, Surface sur) {
+        validate();
+        rsnAllocationSetSurface(mContext, alloc, sur);
+    }
+
+    native void rsnAllocationIoSend(long con, long alloc);
+    synchronized void nAllocationIoSend(long alloc) {
+        validate();
+        rsnAllocationIoSend(mContext, alloc);
+    }
+    native void rsnAllocationIoReceive(long con, long alloc);
+    synchronized void nAllocationIoReceive(long alloc) {
+        validate();
+        rsnAllocationIoReceive(mContext, alloc);
+    }
+    native ByteBuffer rsnAllocationGetByteBuffer(long con, long alloc, int xBytesSize, int dimY, int dimZ);
+    synchronized ByteBuffer nAllocationGetByteBuffer(long alloc, int xBytesSize, int dimY, int dimZ) {
+        validate();
+        return rsnAllocationGetByteBuffer(mContext, alloc, xBytesSize, dimY, dimZ);
+    }
+    native long rsnAllocationGetStride(long con, long alloc);
+    synchronized long nAllocationGetStride(long alloc) {
+        validate();
+        return rsnAllocationGetStride(mContext, alloc);
+    }
+
+    native void rsnAllocationGenerateMipmaps(long con, long alloc);
+    synchronized void nAllocationGenerateMipmaps(long alloc) {
+        validate();
+        rsnAllocationGenerateMipmaps(mContext, alloc);
+    }
+    native void  rsnAllocationCopyFromBitmap(long con, long alloc, Bitmap bmp);
+    synchronized void nAllocationCopyFromBitmap(long alloc, Bitmap bmp) {
+        validate();
+        rsnAllocationCopyFromBitmap(mContext, alloc, bmp);
+    }
+
+
+    native void rsnAllocationData1D(long con, long id, int off, int mip, int count, Object d, int sizeBytes, int dt,
+                                    int mSize, boolean usePadding);
+    synchronized void nAllocationData1D(long id, int off, int mip, int count, Object d, int sizeBytes, Element.DataType dt,
+                                        int mSize, boolean usePadding) {
+        validate();
+        rsnAllocationData1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
+    }
+
+    native void rsnAllocationElementData1D(long con,long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes);
+    synchronized void nAllocationElementData1D(long id, int xoff, int mip, int compIdx, byte[] d, int sizeBytes) {
+        validate();
+        rsnAllocationElementData1D(mContext, id, xoff, mip, compIdx, d, sizeBytes);
+    }
+    /*
+    native void rsnAllocationElementData(long con,long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes);
+    synchronized void nAllocationElementData(long id, int xoff, int yoff, int zoff, int mip, int compIdx, byte[] d, int sizeBytes) {
+        validate();
+        rsnAllocationElementData(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
+    }
+    */
+
+    native void rsnAllocationData2D(long con,
+                                    long dstAlloc, int dstXoff, int dstYoff,
+                                    int dstMip, int dstFace,
+                                    int width, int height,
+                                    long srcAlloc, int srcXoff, int srcYoff,
+                                    int srcMip, int srcFace);
+    synchronized void nAllocationData2D(long dstAlloc, int dstXoff, int dstYoff,
+                                        int dstMip, int dstFace,
+                                        int width, int height,
+                                        long srcAlloc, int srcXoff, int srcYoff,
+                                        int srcMip, int srcFace) {
+        validate();
+        rsnAllocationData2D(mContext,
+                            dstAlloc, dstXoff, dstYoff,
+                            dstMip, dstFace,
+                            width, height,
+                            srcAlloc, srcXoff, srcYoff,
+                            srcMip, srcFace);
+    }
+
+    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face,
+                                    int w, int h, Object d, int sizeBytes, int dt,
+                                    int mSize, boolean usePadding);
+    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face,
+                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
+                                        int mSize, boolean usePadding) {
+        validate();
+        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
+    }
+
+    native void rsnAllocationData2D(long con, long id, int xoff, int yoff, int mip, int face, Bitmap b);
+    synchronized void nAllocationData2D(long id, int xoff, int yoff, int mip, int face, Bitmap b) {
+        validate();
+        rsnAllocationData2D(mContext, id, xoff, yoff, mip, face, b);
+    }
+
+    native void rsnAllocationData3D(long con,
+                                    long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
+                                    int dstMip,
+                                    int width, int height, int depth,
+                                    long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
+                                    int srcMip);
+    synchronized void nAllocationData3D(long dstAlloc, int dstXoff, int dstYoff, int dstZoff,
+                                        int dstMip,
+                                        int width, int height, int depth,
+                                        long srcAlloc, int srcXoff, int srcYoff, int srcZoff,
+                                        int srcMip) {
+        validate();
+        rsnAllocationData3D(mContext,
+                            dstAlloc, dstXoff, dstYoff, dstZoff,
+                            dstMip, width, height, depth,
+                            srcAlloc, srcXoff, srcYoff, srcZoff, srcMip);
+    }
+
+
+    native void rsnAllocationData3D(long con, long id, int xoff, int yoff, int zoff, int mip,
+                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
+                                    int mSize, boolean usePadding);
+    synchronized void nAllocationData3D(long id, int xoff, int yoff, int zoff, int mip,
+                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
+                                        int mSize, boolean usePadding) {
+        validate();
+        rsnAllocationData3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes,
+                            dt.mID, mSize, usePadding);
+    }
+
+    native void rsnAllocationRead(long con, long id, Object d, int dt, int mSize, boolean usePadding);
+    synchronized void nAllocationRead(long id, Object d, Element.DataType dt, int mSize, boolean usePadding) {
+        validate();
+        rsnAllocationRead(mContext, id, d, dt.mID, mSize, usePadding);
+    }
+
+    native void rsnAllocationRead1D(long con, long id, int off, int mip, int count, Object d,
+                                    int sizeBytes, int dt, int mSize, boolean usePadding);
+    synchronized void nAllocationRead1D(long id, int off, int mip, int count, Object d,
+                                        int sizeBytes, Element.DataType dt, int mSize, boolean usePadding) {
+        validate();
+        rsnAllocationRead1D(mContext, id, off, mip, count, d, sizeBytes, dt.mID, mSize, usePadding);
+    }
+
+    /*
+    native void rsnAllocationElementRead(long con,long id, int xoff, int yoff, int zoff,
+                                         int mip, int compIdx, byte[] d, int sizeBytes);
+    synchronized void nAllocationElementRead(long id, int xoff, int yoff, int zoff,
+                                             int mip, int compIdx, byte[] d, int sizeBytes) {
+        validate();
+        rsnAllocationElementRead(mContext, id, xoff, yoff, zoff, mip, compIdx, d, sizeBytes);
+    }
+    */
+
+    native void rsnAllocationRead2D(long con, long id, int xoff, int yoff, int mip, int face,
+                                    int w, int h, Object d, int sizeBytes, int dt,
+                                    int mSize, boolean usePadding);
+    synchronized void nAllocationRead2D(long id, int xoff, int yoff, int mip, int face,
+                                        int w, int h, Object d, int sizeBytes, Element.DataType dt,
+                                        int mSize, boolean usePadding) {
+        validate();
+        rsnAllocationRead2D(mContext, id, xoff, yoff, mip, face, w, h, d, sizeBytes, dt.mID, mSize, usePadding);
+    }
+
+    /*
+    native void rsnAllocationRead3D(long con, long id, int xoff, int yoff, int zoff, int mip,
+                                    int w, int h, int depth, Object d, int sizeBytes, int dt,
+                                    int mSize, boolean usePadding);
+    synchronized void nAllocationRead3D(long id, int xoff, int yoff, int zoff, int mip,
+                                        int w, int h, int depth, Object d, int sizeBytes, Element.DataType dt,
+                                        int mSize, boolean usePadding) {
+        validate();
+        rsnAllocationRead3D(mContext, id, xoff, yoff, zoff, mip, w, h, depth, d, sizeBytes, dt.mID, mSize, usePadding);
+    }
+    */
+
+    native long  rsnAllocationGetType(long con, long id);
+    synchronized long nAllocationGetType(long id) {
+        validate();
+        return rsnAllocationGetType(mContext, id);
+    }
+
+    native void rsnAllocationResize1D(long con, long id, int dimX);
+    synchronized void nAllocationResize1D(long id, int dimX) {
+        validate();
+        rsnAllocationResize1D(mContext, id, dimX);
+    }
+    native void rsnAllocationResize2D(long con, long id, int dimX, int dimY);
+    synchronized void nAllocationResize2D(long id, int dimX, int dimY) {
+        validate();
+        rsnAllocationResize2D(mContext, id, dimX, dimY);
+    }
+
+    native void rsnScriptBindAllocation(long con, long script, long alloc, int slot, boolean mUseInc);
+    synchronized void nScriptBindAllocation(long script, long alloc, int slot, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptBindAllocation(curCon, script, alloc, slot, mUseInc);
+    }
+    native void rsnScriptSetTimeZone(long con, long script, byte[] timeZone, boolean mUseInc);
+    synchronized void nScriptSetTimeZone(long script, byte[] timeZone, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptSetTimeZone(curCon, script, timeZone, mUseInc);
+    }
+    native void rsnScriptInvoke(long con, long id, int slot, boolean mUseInc);
+    synchronized void nScriptInvoke(long id, int slot, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptInvoke(curCon, id, slot, mUseInc);
+    }
+    native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, byte[] params, boolean mUseInc);
+    native void rsnScriptForEach(long con, long incCon, long id, int slot, long ain, long aout, boolean mUseInc);
+    native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout, byte[] params,
+                                        int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
+    native void rsnScriptForEachClipped(long con, long incCon, long id, int slot, long ain, long aout,
+                                        int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc);
+    synchronized void nScriptForEach(long id, int slot, long ain, long aout, byte[] params, boolean mUseInc) {
+        validate();
+        if (params == null) {
+            rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, mUseInc);
+        } else {
+            rsnScriptForEach(mContext, mIncCon, id, slot, ain, aout, params, mUseInc);
+        }
+    }
+
+    synchronized void nScriptForEachClipped(long id, int slot, long ain, long aout, byte[] params,
+                                            int xstart, int xend, int ystart, int yend, int zstart, int zend, boolean mUseInc) {
+        validate();
+        if (params == null) {
+            rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, xstart, xend, ystart, yend, zstart, zend, mUseInc);
+        } else {
+            rsnScriptForEachClipped(mContext, mIncCon, id, slot, ain, aout, params, xstart, xend, ystart, yend, zstart, zend, mUseInc);
+        }
+    }
+
+    native void rsnScriptForEach(long con, long id, int slot, long[] ains,
+                                 long aout, byte[] params, int[] limits);
+
+    synchronized void nScriptForEach(long id, int slot, long[] ains, long aout,
+                                     byte[] params, int[] limits) {
+        if (!mEnableMultiInput) {
+            Log.e(LOG_TAG, "Multi-input kernels are not supported, please change targetSdkVersion to >= 23");
+            throw new RSRuntimeException("Multi-input kernels are not supported before API 23)");
+        }
+        validate();
+        rsnScriptForEach(mContext, id, slot, ains, aout, params, limits);
+    }
+
+    native void rsnScriptReduce(long con, long id, int slot, long[] ains,
+                                long aout, int[] limits);
+    synchronized void nScriptReduce(long id, int slot, long ains[], long aout,
+                                    int[] limits) {
+        validate();
+        rsnScriptReduce(mContext, id, slot, ains, aout, limits);
+    }
+
+    native void rsnScriptInvokeV(long con, long id, int slot, byte[] params, boolean mUseInc);
+    synchronized void nScriptInvokeV(long id, int slot, byte[] params, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptInvokeV(curCon, id, slot, params, mUseInc);
+    }
+    native void rsnScriptSetVarI(long con, long id, int slot, int val, boolean mUseInc);
+    synchronized void nScriptSetVarI(long id, int slot, int val, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptSetVarI(curCon, id, slot, val, mUseInc);
+    }
+    native void rsnScriptSetVarJ(long con, long id, int slot, long val, boolean mUseInc);
+    synchronized void nScriptSetVarJ(long id, int slot, long val, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptSetVarJ(curCon, id, slot, val, mUseInc);
+    }
+    native void rsnScriptSetVarF(long con, long id, int slot, float val, boolean mUseInc);
+    synchronized void nScriptSetVarF(long id, int slot, float val, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptSetVarF(curCon, id, slot, val, mUseInc);
+    }
+    native void rsnScriptSetVarD(long con, long id, int slot, double val, boolean mUseInc);
+    synchronized void nScriptSetVarD(long id, int slot, double val, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptSetVarD(curCon, id, slot, val, mUseInc);
+    }
+    native void rsnScriptSetVarV(long con, long id, int slot, byte[] val, boolean mUseInc);
+    synchronized void nScriptSetVarV(long id, int slot, byte[] val, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptSetVarV(curCon, id, slot, val, mUseInc);
+    }
+    native void rsnScriptSetVarVE(long con, long id, int slot, byte[] val,
+                                  long e, int[] dims, boolean mUseInc);
+    synchronized void nScriptSetVarVE(long id, int slot, byte[] val,
+                                      long e, int[] dims, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptSetVarVE(curCon, id, slot, val, e, dims, mUseInc);
+    }
+    native void rsnScriptSetVarObj(long con, long id, int slot, long val, boolean mUseInc);
+    synchronized void nScriptSetVarObj(long id, int slot, long val, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        rsnScriptSetVarObj(curCon, id, slot, val, mUseInc);
+    }
+
+    native long  rsnScriptCCreate(long con, String resName, String cacheDir,
+                                 byte[] script, int length);
+    synchronized long nScriptCCreate(String resName, String cacheDir, byte[] script, int length) {
+        validate();
+        return rsnScriptCCreate(mContext, resName, cacheDir, script, length);
+    }
+
+    native long  rsnScriptIntrinsicCreate(long con, int id, long eid, boolean mUseInc);
+    synchronized long nScriptIntrinsicCreate(int id, long eid, boolean mUseInc) {
+        validate();
+        if (mUseInc) {
+            if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.LOLLIPOP) {
+                Log.e(LOG_TAG, "Incremental Intrinsics are not supported, please change targetSdkVersion to >= 21");
+                throw new RSRuntimeException("Incremental Intrinsics are not supported before Lollipop (API 21)");
+            }
+
+            if (!mIncLoaded) {
+                try {
+                    System.loadLibrary("RSSupport");
+                } catch (UnsatisfiedLinkError e) {
+                    Log.e(LOG_TAG, "Error loading RS Compat library for Incremental Intrinsic Support: " + e);
+                    throw new RSRuntimeException("Error loading RS Compat library for Incremental Intrinsic Support: " + e);
+                }
+                if (!nIncLoadSO(SUPPORT_LIB_API, mNativeLibDir + "/libRSSupport.so")) {
+                    throw new RSRuntimeException("Error loading libRSSupport library for Incremental Intrinsic Support");
+                }
+                mIncLoaded = true;
+            }
+            if (mIncCon == 0) {
+                //Create a dummy compat context (synchronous).
+                long device = nIncDeviceCreate();
+                mIncCon = nIncContextCreate(device, 0, 0, 0);
+            }
+            return rsnScriptIntrinsicCreate(mIncCon, id, eid, mUseInc);
+        } else {
+            return rsnScriptIntrinsicCreate(mContext, id, eid, mUseInc);
+        }
+    }
+
+    native long  rsnScriptKernelIDCreate(long con, long sid, int slot, int sig, boolean mUseInc);
+    synchronized long nScriptKernelIDCreate(long sid, int slot, int sig, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        return rsnScriptKernelIDCreate(curCon, sid, slot, sig, mUseInc);
+    }
+
+    native long  rsnScriptInvokeIDCreate(long con, long sid, int slot);
+    synchronized long nScriptInvokeIDCreate(long sid, int slot) {
+        validate();
+        return rsnScriptInvokeIDCreate(mContext, sid, slot);
+    }
+
+    native long  rsnScriptFieldIDCreate(long con, long sid, int slot, boolean mUseInc);
+    synchronized long nScriptFieldIDCreate(long sid, int slot, boolean mUseInc) {
+        validate();
+        long curCon = mContext;
+        if (mUseInc) {
+            curCon = mIncCon;
+        }
+        return rsnScriptFieldIDCreate(curCon, sid, slot, mUseInc);
+    }
+
+    native long  rsnScriptGroupCreate(long con, long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types);
+    synchronized long nScriptGroupCreate(long[] kernels, long[] src, long[] dstk, long[] dstf, long[] types) {
+        validate();
+        return rsnScriptGroupCreate(mContext, kernels, src, dstk, dstf, types);
+    }
+
+    native void rsnScriptGroupSetInput(long con, long group, long kernel, long alloc);
+    synchronized void nScriptGroupSetInput(long group, long kernel, long alloc) {
+        validate();
+        rsnScriptGroupSetInput(mContext, group, kernel, alloc);
+    }
+
+    native void rsnScriptGroupSetOutput(long con, long group, long kernel, long alloc);
+    synchronized void nScriptGroupSetOutput(long group, long kernel, long alloc) {
+        validate();
+        rsnScriptGroupSetOutput(mContext, group, kernel, alloc);
+    }
+
+    native void rsnScriptGroupExecute(long con, long group);
+    synchronized void nScriptGroupExecute(long group) {
+        validate();
+        rsnScriptGroupExecute(mContext, group);
+    }
+
+    native long  rsnSamplerCreate(long con, int magFilter, int minFilter,
+                                 int wrapS, int wrapT, int wrapR, float aniso);
+    synchronized long nSamplerCreate(int magFilter, int minFilter,
+                                 int wrapS, int wrapT, int wrapR, float aniso) {
+        validate();
+        return rsnSamplerCreate(mContext, magFilter, minFilter, wrapS, wrapT, wrapR, aniso);
+    }
+
+// entry points for ScriptGroup2
+    native long rsnClosureCreate(long con, long kernelID, long returnValue,
+        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
+        long[] depFieldIDs);
+    synchronized long nClosureCreate(long kernelID, long returnValue,
+        long[] fieldIDs, long[] values, int[] sizes, long[] depClosures,
+        long[] depFieldIDs) {
+      validate();
+      long c = rsnClosureCreate(mContext, kernelID, returnValue, fieldIDs, values,
+          sizes, depClosures, depFieldIDs);
+      if (c == 0) {
+          throw new RSRuntimeException("Failed creating closure.");
+      }
+      return c;
+    }
+
+    native long rsnInvokeClosureCreate(long con, long invokeID, byte[] params,
+        long[] fieldIDs, long[] values, int[] sizes);
+    synchronized long nInvokeClosureCreate(long invokeID, byte[] params,
+        long[] fieldIDs, long[] values, int[] sizes) {
+      validate();
+      long c = rsnInvokeClosureCreate(mContext, invokeID, params, fieldIDs,
+          values, sizes);
+      if (c == 0) {
+          throw new RSRuntimeException("Failed creating closure.");
+      }
+      return c;
+    }
+
+    native void rsnClosureSetArg(long con, long closureID, int index,
+      long value, int size);
+    synchronized void nClosureSetArg(long closureID, int index, long value,
+        int size) {
+      validate();
+      rsnClosureSetArg(mContext, closureID, index, value, size);
+    }
+
+    native void rsnClosureSetGlobal(long con, long closureID, long fieldID,
+        long value, int size);
+    // Does this have to be synchronized?
+    synchronized void nClosureSetGlobal(long closureID, long fieldID,
+        long value, int size) {
+      validate(); // TODO: is this necessary?
+      rsnClosureSetGlobal(mContext, closureID, fieldID, value, size);
+    }
+
+    native long rsnScriptGroup2Create(long con, String name, String cachePath,
+                                      long[] closures);
+    synchronized long nScriptGroup2Create(String name, String cachePath,
+                                          long[] closures) {
+      validate();
+      return rsnScriptGroup2Create(mContext, name, cachePath, closures);
+    }
+
+    native void rsnScriptGroup2Execute(long con, long groupID);
+    synchronized void nScriptGroup2Execute(long groupID) {
+      validate();
+      rsnScriptGroup2Execute(mContext, groupID);
+    }
+
+    native void rsnScriptIntrinsicBLAS_Single(long con, long incCon, long id, int func, int TransA,
+                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+                                              float alpha, long A, long B, float beta, long C, int incX, int incY,
+                                              int KL, int KU, boolean mUseInc);
+    synchronized void nScriptIntrinsicBLAS_Single(long id, int func, int TransA,
+                                                  int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+                                                  float alpha, long A, long B, float beta, long C, int incX, int incY,
+                                                  int KL, int KU, boolean mUseInc) {
+        validate();
+        rsnScriptIntrinsicBLAS_Single(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
+    }
+
+    native void rsnScriptIntrinsicBLAS_Double(long con, long incCon, long id, int func, int TransA,
+                                              int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+                                              double alpha, long A, long B, double beta, long C, int incX, int incY,
+                                              int KL, int KU, boolean mUseInc);
+    synchronized void nScriptIntrinsicBLAS_Double(long id, int func, int TransA,
+                                                  int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+                                                  double alpha, long A, long B, double beta, long C, int incX, int incY,
+                                                  int KL, int KU, boolean mUseInc) {
+        validate();
+        rsnScriptIntrinsicBLAS_Double(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU, mUseInc);
+    }
+
+    native void rsnScriptIntrinsicBLAS_Complex(long con, long incCon, long id, int func, int TransA,
+                                               int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+                                               float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
+                                               int KL, int KU, boolean mUseInc);
+    synchronized void nScriptIntrinsicBLAS_Complex(long id, int func, int TransA,
+                                                   int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+                                                   float alphaX, float alphaY, long A, long B, float betaX, float betaY, long C, int incX, int incY,
+                                                   int KL, int KU, boolean mUseInc) {
+        validate();
+        rsnScriptIntrinsicBLAS_Complex(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU, mUseInc);
+    }
+
+    native void rsnScriptIntrinsicBLAS_Z(long con, long incCon, long id, int func, int TransA,
+                                         int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+                                         double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
+                                         int KL, int KU, boolean mUseInc);
+    synchronized void nScriptIntrinsicBLAS_Z(long id, int func, int TransA,
+                                             int TransB, int Side, int Uplo, int Diag, int M, int N, int K,
+                                             double alphaX, double alphaY, long A, long B, double betaX, double betaY, long C, int incX, int incY,
+                                             int KL, int KU, boolean mUseInc) {
+        validate();
+        rsnScriptIntrinsicBLAS_Z(mContext, mIncCon, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU, mUseInc);
+    }
+
+    native void rsnScriptIntrinsicBLAS_BNNM(long con, long incCon, long id, int M, int N, int K,
+                                             long A, int a_offset, long B, int b_offset, long C, int c_offset,
+                                             int c_mult_int, boolean mUseInc);
+    synchronized void nScriptIntrinsicBLAS_BNNM(long id, int M, int N, int K,
+                                             long A, int a_offset, long B, int b_offset, long C, int c_offset,
+                                             int c_mult_int, boolean mUseInc) {
+        validate();
+        rsnScriptIntrinsicBLAS_BNNM(mContext, mIncCon, id, M, N, K, A, a_offset, B, b_offset, C, c_offset, c_mult_int, mUseInc);
+    }
+
+// Additional Entry points For inc libRSSupport
+
+    native boolean nIncLoadSO(int deviceApi, String libPath);
+    native long nIncDeviceCreate();
+    native void nIncDeviceDestroy(long dev);
+    // Methods below are wrapped to protect the non-threadsafe
+    // lockless fifo.
+    native long  rsnIncContextCreate(long dev, int ver, int sdkVer, int contextType);
+    synchronized long nIncContextCreate(long dev, int ver, int sdkVer, int contextType) {
+        return rsnIncContextCreate(dev, ver, sdkVer, contextType);
+    }
+    native void rsnIncContextDestroy(long con);
+    synchronized void nIncContextDestroy() {
+        validate();
+
+        // take teardown lock
+        // teardown lock can only be taken when no objects are being destroyed
+        ReentrantReadWriteLock.WriteLock wlock = mRWLock.writeLock();
+        wlock.lock();
+
+        long curCon = mIncCon;
+        // context is considered dead as of this point
+        mIncCon = 0;
+
+        wlock.unlock();
+        rsnIncContextDestroy(curCon);
+    }
+
+    native void rsnIncContextFinish(long con);
+    synchronized void nIncContextFinish() {
+        validate();
+        rsnIncContextFinish(mIncCon);
+    }
+
+    native void rsnIncObjDestroy(long con, long id);
+    void nIncObjDestroy(long id) {
+        // There is a race condition here.  The calling code may be run
+        // by the gc while teardown is occuring.  This protects againts
+        // deleting dead objects.
+        if (mIncCon != 0) {
+            rsnIncObjDestroy(mIncCon, id);
+        }
+    }
+    native long  rsnIncElementCreate(long con, long type, int kind, boolean norm, int vecSize);
+    synchronized long nIncElementCreate(long type, int kind, boolean norm, int vecSize) {
+        validate();
+        return rsnIncElementCreate(mIncCon, type, kind, norm, vecSize);
+    }
+    native long rsnIncTypeCreate(long con, long eid, int x, int y, int z, boolean mips, boolean faces, int yuv);
+    synchronized long nIncTypeCreate(long eid, int x, int y, int z, boolean mips, boolean faces, int yuv) {
+        validate();
+        return rsnIncTypeCreate(mIncCon, eid, x, y, z, mips, faces, yuv);
+    }
+    native long  rsnIncAllocationCreateTyped(long con, long incCon, long alloc, long type, int xBytesSize);
+    synchronized long nIncAllocationCreateTyped(long alloc, long type, int xBytesSize) {
+        validate();
+        return rsnIncAllocationCreateTyped(mContext, mIncCon, alloc, type, xBytesSize);
+    }
+
+    long     mContext;
+    private boolean mDestroyed = false;
+    //Dummy device & context for Inc Support Lib
+    long     mIncCon;
+    //indicator of whether inc support lib has been loaded or not.
+    boolean  mIncLoaded;
+    ReentrantReadWriteLock mRWLock;
+    @SuppressWarnings({"FieldCanBeLocal"})
+    MessageThread mMessageThread;
+
+    Element mElement_U8;
+    Element mElement_I8;
+    Element mElement_U16;
+    Element mElement_I16;
+    Element mElement_U32;
+    Element mElement_I32;
+    Element mElement_U64;
+    Element mElement_I64;
+    Element mElement_F32;
+    Element mElement_F64;
+    Element mElement_BOOLEAN;
+
+    Element mElement_ELEMENT;
+    Element mElement_TYPE;
+    Element mElement_ALLOCATION;
+    Element mElement_SAMPLER;
+    Element mElement_SCRIPT;
+
+    Element mElement_A_8;
+    Element mElement_RGB_565;
+    Element mElement_RGB_888;
+    Element mElement_RGBA_5551;
+    Element mElement_RGBA_4444;
+    Element mElement_RGBA_8888;
+
+    Element mElement_FLOAT_2;
+    Element mElement_FLOAT_3;
+    Element mElement_FLOAT_4;
+
+    Element mElement_DOUBLE_2;
+    Element mElement_DOUBLE_3;
+    Element mElement_DOUBLE_4;
+
+    Element mElement_UCHAR_2;
+    Element mElement_UCHAR_3;
+    Element mElement_UCHAR_4;
+
+    Element mElement_CHAR_2;
+    Element mElement_CHAR_3;
+    Element mElement_CHAR_4;
+
+    Element mElement_USHORT_2;
+    Element mElement_USHORT_3;
+    Element mElement_USHORT_4;
+
+    Element mElement_SHORT_2;
+    Element mElement_SHORT_3;
+    Element mElement_SHORT_4;
+
+    Element mElement_UINT_2;
+    Element mElement_UINT_3;
+    Element mElement_UINT_4;
+
+    Element mElement_INT_2;
+    Element mElement_INT_3;
+    Element mElement_INT_4;
+
+    Element mElement_ULONG_2;
+    Element mElement_ULONG_3;
+    Element mElement_ULONG_4;
+
+    Element mElement_LONG_2;
+    Element mElement_LONG_3;
+    Element mElement_LONG_4;
+
+    Element mElement_MATRIX_4X4;
+    Element mElement_MATRIX_3X3;
+    Element mElement_MATRIX_2X2;
+
+    Sampler mSampler_CLAMP_NEAREST;
+    Sampler mSampler_CLAMP_LINEAR;
+    Sampler mSampler_CLAMP_LINEAR_MIP_LINEAR;
+    Sampler mSampler_WRAP_NEAREST;
+    Sampler mSampler_WRAP_LINEAR;
+    Sampler mSampler_WRAP_LINEAR_MIP_LINEAR;
+    Sampler mSampler_MIRRORED_REPEAT_NEAREST;
+    Sampler mSampler_MIRRORED_REPEAT_LINEAR;
+    Sampler mSampler_MIRRORED_REPEAT_LINEAR_MIP_LINEAR;
+
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+
+    /**
+     * The base class from which an application should derive in order
+     * to receive RS messages from scripts. When a script calls {@code
+     * rsSendToClient}, the data fields will be filled, and the run
+     * method will be called on a separate thread.  This will occur
+     * some time after {@code rsSendToClient} completes in the script,
+     * as {@code rsSendToClient} is asynchronous. Message handlers are
+     * not guaranteed to have completed when {@link
+     * androidx.renderscript.RenderScript#finish} returns.
+     *
+     */
+    public static class RSMessageHandler implements Runnable {
+        protected int[] mData;
+        protected int mID;
+        protected int mLength;
+        public void run() {
+        }
+    }
+    /**
+     * If an application is expecting messages, it should set this
+     * field to an instance of {@link RSMessageHandler}.  This
+     * instance will receive all the user messages sent from {@code
+     * sendToClient} by scripts from this context.
+     *
+     */
+    RSMessageHandler mMessageCallback = null;
+
+    public void setMessageHandler(RSMessageHandler msg) {
+        mMessageCallback = msg;
+    }
+    public RSMessageHandler getMessageHandler() {
+        return mMessageCallback;
+    }
+
+    /**
+     * Place a message into the message queue to be sent back to the message
+     * handler once all previous commands have been executed.
+     *
+     * @param id
+     * @param data
+     */
+    public void sendMessage(int id, int[] data) {
+        nContextSendMessage(id, data);
+    }
+
+    /**
+     * The runtime error handler base class.  An application should derive from this class
+     * if it wishes to install an error handler.  When errors occur at runtime,
+     * the fields in this class will be filled, and the run method will be called.
+     *
+     */
+    public static class RSErrorHandler implements Runnable {
+        protected String mErrorMessage;
+        protected int mErrorNum;
+        public void run() {
+        }
+    }
+
+    /**
+     * Application Error handler.  All runtime errors will be dispatched to the
+     * instance of RSAsyncError set here.  If this field is null a
+     * {@link RSRuntimeException} will instead be thrown with details about the error.
+     * This will cause program termaination.
+     *
+     */
+    RSErrorHandler mErrorCallback = null;
+
+    public void setErrorHandler(RSErrorHandler msg) {
+        mErrorCallback = msg;
+    }
+    public RSErrorHandler getErrorHandler() {
+        return mErrorCallback;
+    }
+
+    /**
+     * RenderScript worker thread priority enumeration.  The default value is
+     * NORMAL.  Applications wishing to do background processing should set
+     * their priority to LOW to avoid starving forground processes.
+     */
+    public enum Priority {
+        LOW (Process.THREAD_PRIORITY_BACKGROUND + (5 * Process.THREAD_PRIORITY_LESS_FAVORABLE)),
+        NORMAL (Process.THREAD_PRIORITY_DISPLAY);
+
+        int mID;
+        Priority(int id) {
+            mID = id;
+        }
+    }
+
+    void validateObject(BaseObj o) {
+        if (o != null) {
+            if (o.mRS != this) {
+                throw new RSIllegalArgumentException("Attempting to use an object across contexts.");
+            }
+        }
+    }
+
+    void validate() {
+        if (mContext == 0) {
+            throw new RSInvalidStateException("Calling RS with no Context active.");
+        }
+    }
+
+    /**
+     * check if IO support lib is available.
+     */
+    boolean usingIO() {
+        return useIOlib;
+    }
+    /**
+     * Change the priority of the worker threads for this context.
+     *
+     * @param p New priority to be set.
+     */
+    public void setPriority(Priority p) {
+        validate();
+        nContextSetPriority(p.mID);
+    }
+
+    static class MessageThread extends Thread {
+        RenderScript mRS;
+        boolean mRun = true;
+        int[] mAuxData = new int[2];
+
+        static final int RS_MESSAGE_TO_CLIENT_NONE = 0;
+        static final int RS_MESSAGE_TO_CLIENT_EXCEPTION = 1;
+        static final int RS_MESSAGE_TO_CLIENT_RESIZE = 2;
+        static final int RS_MESSAGE_TO_CLIENT_ERROR = 3;
+
+        static final int RS_MESSAGE_TO_CLIENT_USER = 4;
+        static final int RS_ERROR_FATAL_DEBUG = 0x800;
+        static final int RS_ERROR_FATAL_UNKNOWN = 0x1000;
+
+        MessageThread(RenderScript rs) {
+            super("RSMessageThread");
+            mRS = rs;
+
+        }
+
+        public void run() {
+            // This function is a temporary solution.  The final solution will
+            // used typed allocations where the message id is the type indicator.
+            int[] rbuf = new int[16];
+            mRS.nContextInitToClient(mRS.mContext);
+            while(mRun) {
+                rbuf[0] = 0;
+                int msg = mRS.nContextPeekMessage(mRS.mContext, mAuxData);
+                int size = mAuxData[1];
+                int subID = mAuxData[0];
+
+                if (msg == RS_MESSAGE_TO_CLIENT_USER) {
+                    if ((size>>2) >= rbuf.length) {
+                        rbuf = new int[(size + 3) >> 2];
+                    }
+                    if (mRS.nContextGetUserMessage(mRS.mContext, rbuf) !=
+                        RS_MESSAGE_TO_CLIENT_USER) {
+                        throw new RSDriverException("Error processing message from RenderScript.");
+                    }
+
+                    if(mRS.mMessageCallback != null) {
+                        mRS.mMessageCallback.mData = rbuf;
+                        mRS.mMessageCallback.mID = subID;
+                        mRS.mMessageCallback.mLength = size;
+                        mRS.mMessageCallback.run();
+                    } else {
+                        throw new RSInvalidStateException("Received a message from the script with no message handler installed.");
+                    }
+                    continue;
+                }
+
+                if (msg == RS_MESSAGE_TO_CLIENT_ERROR) {
+                    String e = mRS.nContextGetErrorMessage(mRS.mContext);
+
+                    // Copied from java/android/renderscript/RenderScript.java
+                    // Throw RSRuntimeException under the following conditions:
+                    //
+                    // 1) It is an unknown fatal error.
+                    // 2) It is a debug fatal error, and we are not in a
+                    //    debug context.
+                    // 3) It is a debug fatal error, and we do not have an
+                    //    error callback.
+                    if (subID >= RS_ERROR_FATAL_UNKNOWN ||
+                        (subID >= RS_ERROR_FATAL_DEBUG &&
+                         (mRS.mContextType != ContextType.DEBUG ||
+                          mRS.mErrorCallback == null))) {
+                        android.util.Log.e(LOG_TAG, "fatal RS error, " + e);
+                        throw new RSRuntimeException("Fatal error " + subID + ", details: " + e);
+                    }
+
+                    if(mRS.mErrorCallback != null) {
+                        mRS.mErrorCallback.mErrorMessage = e;
+                        mRS.mErrorCallback.mErrorNum = subID;
+                        mRS.mErrorCallback.run();
+                    } else {
+                        android.util.Log.e(LOG_TAG, "non fatal RS error, " + e);
+                        // Do not throw here. In these cases, we do not have
+                        // a fatal error.
+                    }
+                    continue;
+                }
+
+                // 2: teardown.
+                // But we want to avoid starving other threads during
+                // teardown by yielding until the next line in the destructor
+                // can execute to set mRun = false
+                try {
+                    sleep(1, 0);
+                } catch(InterruptedException e) {
+                }
+            }
+            //Log.d(LOG_TAG, "MessageThread exiting.");
+        }
+    }
+
+    RenderScript(Context ctx) {
+        mContextType = ContextType.NORMAL;
+        if (ctx != null) {
+            mApplicationContext = ctx.getApplicationContext();
+            // Only set mNativeLibDir for API 9+.
+            mNativeLibDir = mApplicationContext.getApplicationInfo().nativeLibraryDir;
+        }
+        mIncCon = 0;
+        mIncLoaded = false;
+        mRWLock = new ReentrantReadWriteLock();
+    }
+
+    /**
+     * Gets the application context associated with the RenderScript context.
+     *
+     * @return The application context.
+     */
+    public final Context getApplicationContext() {
+        return mApplicationContext;
+    }
+
+    /**
+     * Create a RenderScript context.
+     *
+     * @param ctx The context.
+     * @return RenderScript
+     */
+    private static RenderScript internalCreate(Context ctx, int sdkVersion, ContextType ct, int flags) {
+        RenderScript rs = new RenderScript(ctx);
+
+        if (sSdkVersion == -1) {
+            sSdkVersion = sdkVersion;
+        } else if (sSdkVersion != sdkVersion) {
+            throw new RSRuntimeException("Can't have two contexts with different SDK versions in support lib");
+        }
+        useNative = setupNative(sSdkVersion, ctx);
+        synchronized(lock) {
+            if (sInitialized == false) {
+                try {
+                    Class<?> vm_runtime = Class.forName("dalvik.system.VMRuntime");
+                    Method get_runtime = vm_runtime.getDeclaredMethod("getRuntime");
+                    sRuntime = get_runtime.invoke(null);
+                    Class<?> argClass = android.os.Build.VERSION.SDK_INT >= 29 ? Long.TYPE : Integer.TYPE;
+                    // The int version is (so far) always defined, but deprecated for APIs >= 29.
+                    registerNativeAllocation = vm_runtime.getDeclaredMethod("registerNativeAllocation", argClass);
+                    registerNativeFree = vm_runtime.getDeclaredMethod("registerNativeFree", argClass);
+                    sUseGCHooks = true;
+                } catch (Exception e) {
+                    Log.e(LOG_TAG, "No GC methods");
+                    sUseGCHooks = false;
+                }
+                try {
+                    // For API 9 - 22, always use the absolute path of librsjni.so
+                    // http://b/25226912
+                    if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
+                        rs.mNativeLibDir != null) {
+                        System.load(rs.mNativeLibDir + "/librsjni.so");
+                    } else {
+                        System.loadLibrary("rsjni");
+                    }
+                    sInitialized = true;
+                    sPointerSize = rsnSystemGetPointerSize();
+                } catch (UnsatisfiedLinkError e) {
+                    Log.e(LOG_TAG, "Error loading RS jni library: " + e);
+                    throw new RSRuntimeException("Error loading RS jni library: " + e + " Support lib API: " + SUPPORT_LIB_VERSION);
+                }
+            }
+        }
+
+        if (useNative) {
+            android.util.Log.v(LOG_TAG, "RS native mode");
+        } else {
+            android.util.Log.v(LOG_TAG, "RS compat mode");
+        }
+
+        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
+            useIOlib = true;
+        }
+
+        // The target API level used to init dispatchTable.
+        int dispatchAPI = sdkVersion;
+        if (sdkVersion < android.os.Build.VERSION.SDK_INT) {
+            // If the device API is higher than target API level, init dispatch table based on device API.
+            dispatchAPI = android.os.Build.VERSION.SDK_INT;
+        }
+
+        String rssupportPath = null;
+        // For API 9 - 22, always use the absolute path of libRSSupport.so
+        // http://b/25226912
+        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
+            rs.mNativeLibDir != null) {
+            rssupportPath = rs.mNativeLibDir + "/libRSSupport.so";
+        }
+        if (!rs.nLoadSO(useNative, dispatchAPI, rssupportPath)) {
+            if (useNative) {
+                android.util.Log.v(LOG_TAG, "Unable to load libRS.so, falling back to compat mode");
+                useNative = false;
+            }
+            try {
+                if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M &&
+                    rs.mNativeLibDir != null) {
+                    System.load(rssupportPath);
+                } else {
+                    System.loadLibrary("RSSupport");
+                }
+            } catch (UnsatisfiedLinkError e) {
+                Log.e(LOG_TAG, "Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
+                throw new RSRuntimeException("Error loading RS Compat library: " + e + " Support lib version: " + SUPPORT_LIB_VERSION);
+            }
+            if (!rs.nLoadSO(false, dispatchAPI, rssupportPath)) {
+                Log.e(LOG_TAG, "Error loading RS Compat library: nLoadSO() failed; Support lib version: " + SUPPORT_LIB_VERSION);
+                throw new RSRuntimeException("Error loading libRSSupport library, Support lib version: " + SUPPORT_LIB_VERSION);
+            }
+        }
+
+        if (useIOlib) {
+            try {
+                System.loadLibrary("RSSupportIO");
+            } catch (UnsatisfiedLinkError e) {
+                useIOlib = false;
+            }
+            if (!useIOlib || !rs.nLoadIOSO()) {
+                android.util.Log.v(LOG_TAG, "Unable to load libRSSupportIO.so, USAGE_IO not supported");
+                useIOlib = false;
+            }
+        }
+
+        // For old APIs with dlopen bug, need to load blas lib in Java first.
+        // Only try load to blasV8 when the desired API level includes IntrinsicBLAS.
+        if (dispatchAPI >= 23) {
+            // Enable multi-input kernels only when diapatchAPI is M+.
+            rs.mEnableMultiInput = true;
+            try {
+                System.loadLibrary("blasV8");
+            } catch (UnsatisfiedLinkError e) {
+                Log.v(LOG_TAG, "Unable to load BLAS lib, ONLY BNNM will be supported: " + e);
+            }
+        }
+
+        long device = rs.nDeviceCreate();
+        rs.mContext = rs.nContextCreate(device, 0, sdkVersion, ct.mID, rs.mNativeLibDir);
+        rs.mContextType = ct;
+        rs.mContextFlags = flags;
+        rs.mContextSdkVersion = sdkVersion;
+        rs.mDispatchAPILevel = dispatchAPI;
+        if (rs.mContext == 0) {
+            throw new RSDriverException("Failed to create RS context.");
+        }
+        rs.mMessageThread = new MessageThread(rs);
+        rs.mMessageThread.start();
+        return rs;
+    }
+
+    /**
+     * Create a RenderScript context.
+     *
+     * See documentation for @create for details
+     *
+     * @param ctx The context.
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx) {
+        return create(ctx, ContextType.NORMAL);
+    }
+
+    /**
+     * calls create(ctx, ct, CREATE_FLAG_NONE)
+     *
+     * See documentation for @create for details
+     *
+     * @param ctx The context.
+     * @param ct The type of context to be created.
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx, ContextType ct) {
+        return create(ctx, ct, CREATE_FLAG_NONE);
+    }
+
+    /**
+     * Gets or creates a RenderScript context of the specified type.
+     *
+     * The returned context will be cached for future reuse within
+     * the process. When an application is finished using
+     * RenderScript it should call releaseAllContexts()
+     *
+     * A process context is a context designed for easy creation and
+     * lifecycle management.  Multiple calls to this function will
+     * return the same object provided they are called with the same
+     * options.  This allows it to be used any time a RenderScript
+     * context is needed.
+     *
+     *
+     * @param ctx The context.
+     * @param ct The type of context to be created.
+     * @param flags The OR of the CREATE_FLAG_* options desired
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx, ContextType ct, int flags) {
+        int v = ctx.getApplicationInfo().targetSdkVersion;
+        return create(ctx, v, ct, flags);
+    }
+
+    /**
+     * calls create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE)
+     *
+     * Used by the RenderScriptThunker to maintain backward compatibility.
+     *
+     * @hide
+     * @param ctx The context.
+     * @param sdkVersion The target SDK Version.
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx, int sdkVersion) {
+        return create(ctx, sdkVersion, ContextType.NORMAL, CREATE_FLAG_NONE);
+    }
+
+
+    /**
+     * calls create(ctx, sdkVersion, ct, CREATE_FLAG_NONE)
+     * Create a RenderScript context.
+     *
+     * @hide
+     * @param ctx The context.
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct) {
+        return create(ctx, sdkVersion, ct, CREATE_FLAG_NONE);
+    }
+
+     /**
+     * Gets or creates a RenderScript context of the specified type.
+     *
+     * @param ctx The context.
+     * @param ct The type of context to be created.
+     * @param sdkVersion The target SDK Version.
+     * @param flags The OR of the CREATE_FLAG_* options desired
+     * @return RenderScript
+     */
+    public static RenderScript create(Context ctx, int sdkVersion, ContextType ct, int flags) {
+        synchronized (mProcessContextList) {
+            for (RenderScript prs : mProcessContextList) {
+                if ((prs.mContextType == ct) &&
+                    (prs.mContextFlags == flags) &&
+                    (prs.mContextSdkVersion == sdkVersion)) {
+
+                    return prs;
+                }
+            }
+
+            RenderScript prs = internalCreate(ctx, sdkVersion, ct, flags);
+            prs.mIsProcessContext = true;
+            mProcessContextList.add(prs);
+            return prs;
+        }
+    }
+
+    /**
+     *
+     * Releases all the process contexts.  This is the same as
+     * calling .destroy() on each unique context retreived with
+     * create(...). If no contexts have been created this
+     * function does nothing.
+     *
+     * Typically you call this when your application is losing focus
+     * and will not be using a context for some time.
+     *
+     * This has no effect on a context created with
+     * createMultiContext()
+     */
+    public static void releaseAllContexts() {
+        ArrayList<RenderScript> oldList;
+        synchronized (mProcessContextList) {
+            oldList = mProcessContextList;
+            mProcessContextList = new ArrayList<RenderScript>();
+        }
+
+        for (RenderScript prs : oldList) {
+            prs.mIsProcessContext = false;
+            prs.destroy();
+        }
+        oldList.clear();
+    }
+
+
+
+    /**
+     * Create a RenderScript context.
+     *
+     * This is an advanced function intended for applications which
+     * need to create more than one RenderScript context to be used
+     * at the same time.
+     *
+     * If you need a single context please use create()
+     *
+     * @param ctx The context.
+     * @return RenderScript
+     */
+    public static RenderScript createMultiContext(Context ctx, ContextType ct, int flags, int API_number) {
+        return internalCreate(ctx, API_number, ct, flags);
+    }
+
+    /**
+     * Print the currently available debugging information about the state of
+     * the RS context to the log.
+     *
+     */
+    public void contextDump() {
+        validate();
+        nContextDump(0);
+    }
+
+    /**
+     * Wait for any pending asynchronous opeations (such as copies to a RS
+     * allocation or RS script executions) to complete.
+     *
+     */
+    public void finish() {
+        nContextFinish();
+    }
+
+    private void helpDestroy() {
+        boolean shouldDestroy = false;
+        synchronized(this) {
+            if (!mDestroyed) {
+                shouldDestroy = true;
+                mDestroyed = true;
+            }
+        }
+
+        if (shouldDestroy) {
+            nContextFinish();
+            if (mIncCon != 0) {
+                nIncContextFinish();
+                nIncContextDestroy();
+                mIncCon = 0;
+            }
+            nContextDeinitToClient(mContext);
+            mMessageThread.mRun = false;
+            // Interrupt mMessageThread so it gets to see immediately that mRun is false
+            // and exit rightaway.
+            mMessageThread.interrupt();
+
+            // Wait for mMessageThread to join.  Try in a loop, in case this thread gets interrupted
+            // during the wait.  If interrupted, set the "interrupted" status of the current thread.
+            boolean hasJoined = false, interrupted = false;
+            while (!hasJoined) {
+                try {
+                    mMessageThread.join();
+                    hasJoined = true;
+                } catch (InterruptedException e) {
+                    interrupted = true;
+                }
+            }
+            if (interrupted) {
+                Log.v(LOG_TAG, "Interrupted during wait for MessageThread to join");
+                Thread.currentThread().interrupt();
+            }
+
+            nContextDestroy();
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        helpDestroy();
+        super.finalize();
+    }
+
+    /**
+     * Destroys this RenderScript context.  Once this function is called,
+     * using this context or any objects belonging to this context is
+     * illegal.
+     *
+     * This function is a NOP if the context was created
+     * with create().  Please use releaseAllContexts() to clean up
+     * contexts created with the create function.
+     */
+    public void destroy() {
+        if (mIsProcessContext) {
+            // users cannot destroy a process context
+            return;
+        }
+        validate();
+        helpDestroy();
+    }
+
+    boolean isAlive() {
+        return mContext != 0;
+    }
+
+    long safeID(BaseObj o) {
+        if(o != null) {
+            return o.getID(this);
+        }
+        return 0;
+    }
+}
diff --git a/androidx/renderscript/Sampler.java b/androidx/renderscript/Sampler.java
new file mode 100644
index 0000000..57b94d5
--- /dev/null
+++ b/androidx/renderscript/Sampler.java
@@ -0,0 +1,346 @@
+/*
+ * 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 androidx.renderscript;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.Log;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+/**
+ * Sampler object that defines how Allocations can be read as textures within a
+ * kernel. Samplers are used in conjunction with the {@code rsSample} runtime
+ * function to return values from normalized coordinates.
+ *
+ * Any Allocation used with a Sampler must have been created with {@link
+ * androidx.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE}; using a
+ * Sampler on an {@link androidx.renderscript.Allocation} that was not
+ * created with
+ * {@link androidx.renderscript.Allocation#USAGE_GRAPHICS_TEXTURE} is
+ * undefined.
+ **/
+public class Sampler extends BaseObj {
+    public enum Value {
+        NEAREST (0),
+        LINEAR (1),
+        LINEAR_MIP_LINEAR (2),
+        LINEAR_MIP_NEAREST (5),
+        WRAP (3),
+        CLAMP (4),
+        MIRRORED_REPEAT (6);
+
+        int mID;
+        Value(int id) {
+            mID = id;
+        }
+    }
+
+    Value mMin;
+    Value mMag;
+    Value mWrapS;
+    Value mWrapT;
+    Value mWrapR;
+    float mAniso;
+
+    Sampler(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * @return minification setting for the sampler
+     */
+    public Value getMinification() {
+        return mMin;
+    }
+
+    /**
+     * @return magnification setting for the sampler
+     */
+    public Value getMagnification() {
+        return mMag;
+    }
+
+    /**
+     * @return S wrapping mode for the sampler
+     */
+    public Value getWrapS() {
+        return mWrapS;
+    }
+
+    /**
+     * @return T wrapping mode for the sampler
+     */
+    public Value getWrapT() {
+        return mWrapT;
+    }
+
+    /**
+     * @return anisotropy setting for the sampler
+     */
+    public float getAnisotropy() {
+        return mAniso;
+    }
+
+    /**
+     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+     * clamp.
+     *
+     * @param rs Context to which the sampler will belong.
+     *
+     * @return Sampler
+     */
+    public static Sampler CLAMP_NEAREST(RenderScript rs) {
+        if(rs.mSampler_CLAMP_NEAREST == null) {
+            Builder b = new Builder(rs);
+            b.setMinification(Value.NEAREST);
+            b.setMagnification(Value.NEAREST);
+            b.setWrapS(Value.CLAMP);
+            b.setWrapT(Value.CLAMP);
+            rs.mSampler_CLAMP_NEAREST = b.create();
+        }
+        return rs.mSampler_CLAMP_NEAREST;
+    }
+
+    /**
+     * Retrieve a sampler with min and mag set to linear and wrap modes set to
+     * clamp.
+     *
+     * @param rs Context to which the sampler will belong.
+     *
+     * @return Sampler
+     */
+    public static Sampler CLAMP_LINEAR(RenderScript rs) {
+        if(rs.mSampler_CLAMP_LINEAR == null) {
+            Builder b = new Builder(rs);
+            b.setMinification(Value.LINEAR);
+            b.setMagnification(Value.LINEAR);
+            b.setWrapS(Value.CLAMP);
+            b.setWrapT(Value.CLAMP);
+            rs.mSampler_CLAMP_LINEAR = b.create();
+        }
+        return rs.mSampler_CLAMP_LINEAR;
+    }
+
+    /**
+     * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
+     * wrap modes set to clamp.
+     *
+     * @param rs Context to which the sampler will belong.
+     *
+     * @return Sampler
+     */
+    public static Sampler CLAMP_LINEAR_MIP_LINEAR(RenderScript rs) {
+        if(rs.mSampler_CLAMP_LINEAR_MIP_LINEAR == null) {
+            Builder b = new Builder(rs);
+            b.setMinification(Value.LINEAR_MIP_LINEAR);
+            b.setMagnification(Value.LINEAR);
+            b.setWrapS(Value.CLAMP);
+            b.setWrapT(Value.CLAMP);
+            rs.mSampler_CLAMP_LINEAR_MIP_LINEAR = b.create();
+        }
+        return rs.mSampler_CLAMP_LINEAR_MIP_LINEAR;
+    }
+
+    /**
+     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+     * wrap.
+     *
+     * @param rs Context to which the sampler will belong.
+     *
+     * @return Sampler
+     */
+    public static Sampler WRAP_NEAREST(RenderScript rs) {
+        if(rs.mSampler_WRAP_NEAREST == null) {
+            Builder b = new Builder(rs);
+            b.setMinification(Value.NEAREST);
+            b.setMagnification(Value.NEAREST);
+            b.setWrapS(Value.WRAP);
+            b.setWrapT(Value.WRAP);
+            rs.mSampler_WRAP_NEAREST = b.create();
+        }
+        return rs.mSampler_WRAP_NEAREST;
+    }
+
+    /**
+     * Retrieve a sampler with min and mag set to linear and wrap modes set to
+     * wrap.
+     *
+     * @param rs Context to which the sampler will belong.
+     *
+     * @return Sampler
+     */
+    public static Sampler WRAP_LINEAR(RenderScript rs) {
+        if(rs.mSampler_WRAP_LINEAR == null) {
+            Builder b = new Builder(rs);
+            b.setMinification(Value.LINEAR);
+            b.setMagnification(Value.LINEAR);
+            b.setWrapS(Value.WRAP);
+            b.setWrapT(Value.WRAP);
+            rs.mSampler_WRAP_LINEAR = b.create();
+        }
+        return rs.mSampler_WRAP_LINEAR;
+    }
+
+    /**
+     * Retrieve a sampler with mag set to linear, min linear mipmap linear, and
+     * wrap modes set to wrap.
+     *
+     * @param rs Context to which the sampler will belong.
+     *
+     * @return Sampler
+     */
+    public static Sampler WRAP_LINEAR_MIP_LINEAR(RenderScript rs) {
+        if(rs.mSampler_WRAP_LINEAR_MIP_LINEAR == null) {
+            Builder b = new Builder(rs);
+            b.setMinification(Value.LINEAR_MIP_LINEAR);
+            b.setMagnification(Value.LINEAR);
+            b.setWrapS(Value.WRAP);
+            b.setWrapT(Value.WRAP);
+            rs.mSampler_WRAP_LINEAR_MIP_LINEAR = b.create();
+        }
+        return rs.mSampler_WRAP_LINEAR_MIP_LINEAR;
+    }
+
+    /**
+     * Retrieve a sampler with min and mag set to nearest and wrap modes set to
+     * mirrored repeat.
+     *
+     * @param rs Context to which the sampler will belong.
+     *
+     * @return Sampler
+     */
+    public static Sampler MIRRORED_REPEAT_NEAREST(RenderScript rs) {
+        if(rs.mSampler_MIRRORED_REPEAT_NEAREST == null) {
+            Builder b = new Builder(rs);
+            b.setMinification(Value.NEAREST);
+            b.setMagnification(Value.NEAREST);
+            b.setWrapS(Value.MIRRORED_REPEAT);
+            b.setWrapT(Value.MIRRORED_REPEAT);
+            rs.mSampler_MIRRORED_REPEAT_NEAREST = b.create();
+        }
+        return rs.mSampler_MIRRORED_REPEAT_NEAREST;
+    }
+
+    /**
+     * Retrieve a sampler with min and mag set to linear and wrap modes set to
+     * mirrored repeat.
+     *
+     * @param rs Context to which the sampler will belong.
+     *
+     * @return Sampler
+     */
+    public static Sampler MIRRORED_REPEAT_LINEAR(RenderScript rs) {
+        if(rs.mSampler_MIRRORED_REPEAT_LINEAR == null) {
+            Builder b = new Builder(rs);
+            b.setMinification(Value.LINEAR);
+            b.setMagnification(Value.LINEAR);
+            b.setWrapS(Value.MIRRORED_REPEAT);
+            b.setWrapT(Value.MIRRORED_REPEAT);
+            rs.mSampler_MIRRORED_REPEAT_LINEAR = b.create();
+        }
+        return rs.mSampler_MIRRORED_REPEAT_LINEAR;
+    }
+
+    /**
+     * Builder for creating non-standard samplers.  This is only necessary if
+     * a Sampler with different min and mag modes is desired.
+     */
+    public static class Builder {
+        RenderScript mRS;
+        Value mMin;
+        Value mMag;
+        Value mWrapS;
+        Value mWrapT;
+        Value mWrapR;
+        float mAniso;
+
+        public Builder(RenderScript rs) {
+            mRS = rs;
+            mMin = Value.NEAREST;
+            mMag = Value.NEAREST;
+            mWrapS = Value.WRAP;
+            mWrapT = Value.WRAP;
+            mWrapR = Value.WRAP;
+            mAniso = 1.0f;
+        }
+
+        public void setMinification(Value v) {
+            if (v == Value.NEAREST ||
+                v == Value.LINEAR ||
+                v == Value.LINEAR_MIP_LINEAR ||
+                v == Value.LINEAR_MIP_NEAREST) {
+                mMin = v;
+            } else {
+                throw new IllegalArgumentException("Invalid value");
+            }
+        }
+
+        public void setMagnification(Value v) {
+            if (v == Value.NEAREST || v == Value.LINEAR) {
+                mMag = v;
+            } else {
+                throw new IllegalArgumentException("Invalid value");
+            }
+        }
+
+        public void setWrapS(Value v) {
+            if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
+                mWrapS = v;
+            } else {
+                throw new IllegalArgumentException("Invalid value");
+            }
+        }
+
+        public void setWrapT(Value v) {
+            if (v == Value.WRAP || v == Value.CLAMP || v == Value.MIRRORED_REPEAT) {
+                mWrapT = v;
+            } else {
+                throw new IllegalArgumentException("Invalid value");
+            }
+        }
+
+        public void setAnisotropy(float v) {
+            if(v >= 0.0f) {
+                mAniso = v;
+            } else {
+                throw new IllegalArgumentException("Invalid value");
+            }
+        }
+
+        public Sampler create() {
+            mRS.validate();
+            long id = mRS.nSamplerCreate(mMag.mID, mMin.mID,
+                                        mWrapS.mID, mWrapT.mID, mWrapR.mID, mAniso);
+            Sampler sampler = new Sampler(id, mRS);
+            sampler.mMin = mMin;
+            sampler.mMag = mMag;
+            sampler.mWrapS = mWrapS;
+            sampler.mWrapT = mWrapT;
+            sampler.mWrapR = mWrapR;
+            sampler.mAniso = mAniso;
+            return sampler;
+        }
+    }
+
+}
+
diff --git a/androidx/renderscript/Script.java b/androidx/renderscript/Script.java
new file mode 100644
index 0000000..49c0039
--- /dev/null
+++ b/androidx/renderscript/Script.java
@@ -0,0 +1,701 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.util.SparseArray;
+
+/**
+ * The parent class for all executable scripts. This should not be used by
+ * applications.
+ **/
+public class Script extends BaseObj {
+    /**
+     * Determine if Incremental Intrinsic Support is needed
+     *
+     */
+    private boolean mUseIncSupp;
+    protected void setIncSupp(boolean useInc) {
+        mUseIncSupp = useInc;
+    }
+    protected boolean isIncSupp() {
+        return mUseIncSupp;
+    }
+    /**
+     * An allocation for the compat context will be created when needed
+     * e.g. foreach(ain, aout), setVar(ain);
+     *
+     */
+    long getDummyAlloc(Allocation ain) {
+        long dInElement = 0;
+        long dInType = 0;
+        long dummyAlloc = 0;
+        if (ain != null) {
+            Type inType = ain.getType();
+            dInElement = inType.getElement().getDummyElement(mRS);
+            dInType = inType.getDummyType(mRS, dInElement);
+            int xBytesSize = inType.getX() * inType.getElement().getBytesSize();
+            dummyAlloc = mRS.nIncAllocationCreateTyped(ain.getID(mRS), dInType, xBytesSize);
+            ain.setIncAllocID(dummyAlloc);
+        }
+
+        return dummyAlloc;
+    }
+    /**
+     * KernelID is an identifier for a Script + root function pair. It is used
+     * as an identifier for ScriptGroup creation.
+     *
+     * This class should not be directly created. Instead use the method in the
+     * reflected or intrinsic code "getKernelID_funcname()".
+     *
+     */
+    public static final class KernelID extends BaseObj {
+        android.renderscript.Script.KernelID mN;
+        Script mScript;
+        int mSlot;
+        int mSig;
+        KernelID(long id, RenderScript rs, Script s, int slot, int sig) {
+            super(id, rs);
+            mScript = s;
+            mSlot = slot;
+            mSig = sig;
+        }
+    }
+
+    private final SparseArray<KernelID> mKIDs = new SparseArray<KernelID>();
+    /**
+     * Only to be used by generated reflected classes.
+     *
+     *
+     * @param slot
+     * @param sig
+     * @param ein
+     * @param eout
+     *
+     * @return KernelID
+     */
+    protected KernelID createKernelID(int slot, int sig, Element ein, Element eout) {
+        KernelID k = mKIDs.get(slot);
+        if (k != null) {
+            return k;
+        }
+
+        long id = mRS.nScriptKernelIDCreate(getID(mRS), slot, sig, mUseIncSupp);
+        if (id == 0) {
+            throw new RSDriverException("Failed to create KernelID");
+        }
+
+        k = new KernelID(id, mRS, this, slot, sig);
+
+        mKIDs.put(slot, k);
+        return k;
+    }
+
+    /**
+     * InvokeID is an identifier for a invoke function. It is used
+     * as an identifier for ScriptGroup creation.
+     *
+     * This class should not be directly created. Instead use the method in the
+     * reflected or intrinsic code "getInvokeID_funcname()".
+     *
+     */
+    public static final class InvokeID extends BaseObj {
+        Script mScript;
+        int mSlot;
+        InvokeID(long id, RenderScript rs, Script s, int slot) {
+            super(id, rs);
+            mScript = s;
+            mSlot = slot;
+        }
+    }
+
+    private final SparseArray<InvokeID> mIIDs = new SparseArray<InvokeID>();
+    /**
+     * Only to be used by generated reflected classes.
+     */
+    protected InvokeID createInvokeID(int slot) {
+        InvokeID i = mIIDs.get(slot);
+        if (i != null) {
+            return i;
+        }
+
+        long id = mRS.nScriptInvokeIDCreate(getID(mRS), slot);
+        if (id == 0) {
+            throw new RSDriverException("Failed to create KernelID");
+        }
+
+        i = new InvokeID(id, mRS, this, slot);
+        mIIDs.put(slot, i);
+        return i;
+    }
+
+    /**
+     * FieldID is an identifier for a Script + exported field pair. It is used
+     * as an identifier for ScriptGroup creation.
+     *
+     * This class should not be directly created. Instead use the method in the
+     * reflected or intrinsic code "getFieldID_funcname()".
+     *
+     */
+    public static final class FieldID extends BaseObj {
+        android.renderscript.Script.FieldID mN;
+        Script mScript;
+        int mSlot;
+        FieldID(long id, RenderScript rs, Script s, int slot) {
+            super(id, rs);
+            mScript = s;
+            mSlot = slot;
+        }
+    }
+
+    private final SparseArray<FieldID> mFIDs = new SparseArray();
+    /**
+     * Only to be used by generated reflected classes.
+     *
+     * @param slot
+     * @param e
+     *
+     * @return FieldID
+     */
+    protected FieldID createFieldID(int slot, Element e) {
+        FieldID f = mFIDs.get(slot);
+        if (f != null) {
+            return f;
+        }
+
+        long id = mRS.nScriptFieldIDCreate(getID(mRS), slot, mUseIncSupp);
+        if (id == 0) {
+            throw new RSDriverException("Failed to create FieldID");
+        }
+
+        f = new FieldID(id, mRS, this, slot);
+        mFIDs.put(slot, f);
+        return f;
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param slot
+     */
+    protected void invoke(int slot) {
+        mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param slot
+     * @param v
+     */
+    protected void invoke(int slot, FieldPacker v) {
+        if (v != null) {
+            mRS.nScriptInvokeV(getID(mRS), slot, v.getData(), mUseIncSupp);
+        } else {
+            mRS.nScriptInvoke(getID(mRS), slot, mUseIncSupp);
+        }
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param va
+     * @param slot
+     */
+    public void bindAllocation(Allocation va, int slot) {
+        mRS.validate();
+        if (va != null) {
+            mRS.nScriptBindAllocation(getID(mRS), va.getID(mRS), slot, mUseIncSupp);
+        } else {
+            mRS.nScriptBindAllocation(getID(mRS), 0, slot, mUseIncSupp);
+        }
+    }
+
+    public void setTimeZone(String timeZone) {
+        mRS.validate();
+        try {
+            mRS.nScriptSetTimeZone(getID(mRS), timeZone.getBytes("UTF-8"), mUseIncSupp);
+        } catch (java.io.UnsupportedEncodingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param slot
+     * @param ain
+     * @param aout
+     * @param v
+     */
+    protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v) {
+        if (ain == null && aout == null) {
+            throw new RSIllegalArgumentException(
+                "At least one of ain or aout is required to be non-null.");
+        }
+        long in_id = 0;
+        long out_id = 0;
+        if (ain != null) {
+            in_id = ain.getID(mRS);
+        }
+        if (aout != null) {
+            out_id = aout.getID(mRS);
+        }
+
+        byte[] params = null;
+        if (v != null) {
+            params = v.getData();
+        }
+
+        if (mUseIncSupp) {
+            long ainInc = getDummyAlloc(ain);
+            long aoutInc = getDummyAlloc(aout);
+            mRS.nScriptForEach(getID(mRS), slot, ainInc, aoutInc, params, mUseIncSupp);
+        } else {
+            mRS.nScriptForEach(getID(mRS), slot, in_id, out_id, params, mUseIncSupp);
+        }
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param slot
+     * @param ain
+     * @param aout
+     * @param v
+     * @param sc
+     */
+    protected void forEach(int slot, Allocation ain, Allocation aout, FieldPacker v, LaunchOptions sc) {
+        if (ain == null && aout == null) {
+            throw new RSIllegalArgumentException(
+                "At least one of ain or aout is required to be non-null.");
+        }
+
+        if (sc == null) {
+            forEach(slot, ain, aout, v);
+            return;
+        }
+        long in_id = 0;
+        long out_id = 0;
+        if (ain != null) {
+            in_id = ain.getID(mRS);
+        }
+        if (aout != null) {
+            out_id = aout.getID(mRS);
+        }
+
+        byte[] params = null;
+        if (v != null) {
+            params = v.getData();
+        }
+        if (mUseIncSupp) {
+            long ainInc = getDummyAlloc(ain);
+            long aoutInc = getDummyAlloc(aout);
+            mRS.nScriptForEachClipped(getID(mRS), slot, ainInc, aoutInc, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp);        
+        } else {
+            mRS.nScriptForEachClipped(getID(mRS), slot, in_id, out_id, params, sc.xstart, sc.xend, sc.ystart, sc.yend, sc.zstart, sc.zend, mUseIncSupp);
+        }
+    }
+
+    Script(long id, RenderScript rs) {
+        super(id, rs);
+        mUseIncSupp = false;
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @hide
+     */
+    protected void forEach(int slot, Allocation[] ains, Allocation aout,
+                           FieldPacker v) {
+        forEach(slot, ains, aout, v, null);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @hide
+     */
+    protected void forEach(int slot, Allocation[] ains, Allocation aout,
+                           FieldPacker v, LaunchOptions sc) {
+        // TODO: Is this necessary if nScriptForEach calls validate as well?
+        mRS.validate();
+        if (ains != null) {
+            for (Allocation ain : ains) {
+                mRS.validateObject(ain);
+            }
+        }
+        mRS.validateObject(aout);
+
+        if (ains == null && aout == null) {
+            throw new RSIllegalArgumentException(
+                "At least one of ain or aout is required to be non-null.");
+        }
+
+        long[] in_ids;
+        if (ains != null) {
+            in_ids = new long[ains.length];
+            for (int index = 0; index < ains.length; ++index) {
+                in_ids[index] = ains[index].getID(mRS);
+            }
+        } else {
+            in_ids = null;
+        }
+
+        long out_id = 0;
+        if (aout != null) {
+            out_id = aout.getID(mRS);
+        }
+
+        byte[] params = null;
+        if (v != null) {
+            params = v.getData();
+        }
+
+        int[] limits = null;
+        if (sc != null) {
+            limits = new int[6];
+
+            limits[0] = sc.xstart;
+            limits[1] = sc.xend;
+            limits[2] = sc.ystart;
+            limits[3] = sc.yend;
+            limits[4] = sc.zstart;
+            limits[5] = sc.zend;
+        }
+
+        mRS.nScriptForEach(getID(mRS), slot, in_ids, out_id, params, limits);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.  (General reduction)
+     *
+     * @hide
+     */
+    protected void reduce(int slot, Allocation[] ains, Allocation aout, LaunchOptions sc) {
+        mRS.validate();
+        if (ains == null || ains.length < 1) {
+            throw new RSIllegalArgumentException(
+                "At least one input is required.");
+        }
+        if (aout == null) {
+            throw new RSIllegalArgumentException(
+                "aout is required to be non-null.");
+        }
+        for (Allocation ain : ains) {
+            mRS.validateObject(ain);
+        }
+
+        long[] in_ids = new long[ains.length];
+        for (int index = 0; index < ains.length; ++index) {
+            in_ids[index] = ains[index].getID(mRS);
+        }
+        long out_id = aout.getID(mRS);
+
+        int[] limits = null;
+        if (sc != null) {
+            limits = new int[6];
+
+            limits[0] = sc.xstart;
+            limits[1] = sc.xend;
+            limits[2] = sc.ystart;
+            limits[3] = sc.yend;
+            limits[4] = sc.zstart;
+            limits[5] = sc.zend;
+        }
+
+        mRS.nScriptReduce(getID(mRS), slot, in_ids, out_id, limits);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param index
+     * @param v
+     */
+    public void setVar(int index, float v) {
+        mRS.nScriptSetVarF(getID(mRS), index, v, mUseIncSupp);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param index
+     * @param v
+     */
+    public void setVar(int index, double v) {
+        mRS.nScriptSetVarD(getID(mRS), index, v, mUseIncSupp);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param index
+     * @param v
+     */
+    public void setVar(int index, int v) {
+        mRS.nScriptSetVarI(getID(mRS), index, v, mUseIncSupp);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param index
+     * @param v
+     */
+    public void setVar(int index, long v) {
+        mRS.nScriptSetVarJ(getID(mRS), index, v, mUseIncSupp);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param index
+     * @param v
+     */
+    public void setVar(int index, boolean v) {
+        mRS.nScriptSetVarI(getID(mRS), index, v ? 1 : 0, mUseIncSupp);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param index
+     * @param o
+     */
+    public void setVar(int index, BaseObj o) {
+        if (mUseIncSupp) {
+            long oInc = getDummyAlloc((Allocation)o);
+            mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : oInc, mUseIncSupp);            
+        } else {
+            mRS.nScriptSetVarObj(getID(mRS), index, (o == null) ? 0 : o.getID(mRS), mUseIncSupp);
+        }
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param index
+     * @param v
+     */
+    public void setVar(int index, FieldPacker v) {
+        mRS.nScriptSetVarV(getID(mRS), index, v.getData(), mUseIncSupp);
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     * @param index
+     * @param v
+     * @param e
+     * @param dims
+     */
+    public void setVar(int index, FieldPacker v, Element e, int[] dims) {
+        if (mUseIncSupp) {
+            long dElement = e.getDummyElement(mRS);
+            mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), dElement, dims, mUseIncSupp);
+        } else {
+            mRS.nScriptSetVarVE(getID(mRS), index, v.getData(), e.getID(mRS), dims, mUseIncSupp);
+        }
+    }
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     */
+    public static class Builder {
+        RenderScript mRS;
+
+        Builder(RenderScript rs) {
+            mRS = rs;
+        }
+    }
+
+
+    /**
+     * Only intended for use by generated reflected code.
+     *
+     */
+    public static class FieldBase {
+        protected Element mElement;
+        protected Allocation mAllocation;
+
+        protected void init(RenderScript rs, int dimx) {
+            mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT);
+        }
+
+        protected void init(RenderScript rs, int dimx, int usages) {
+            mAllocation = Allocation.createSized(rs, mElement, dimx, Allocation.USAGE_SCRIPT | usages);
+        }
+
+        protected FieldBase() {
+        }
+
+        public Element getElement() {
+            return mElement;
+        }
+
+        public Type getType() {
+            return mAllocation.getType();
+        }
+
+        public Allocation getAllocation() {
+            return mAllocation;
+        }
+
+        //@Override
+        public void updateAllocation() {
+        }
+    }
+
+
+    /**
+     * Class for specifying the specifics about how a kernel will be
+     * launched.
+     *
+     * This class can specify a potential range of cells on which to
+     * run a kernel.  If no set is called for a dimension then this
+     * class will have no impact on that dimension when the kernel
+     * is executed.
+     *
+     * The forEach kernel launch will operate over the intersection of
+     * the dimensions.
+     *
+     * Example:
+     * LaunchOptions with setX(5, 15)
+     * Allocation with dimension X=10, Y=10
+     * The resulting forEach run would execute over:
+     * x = 5 to 9 (inclusive) and
+     * y = 0 to 9 (inclusive).
+     *
+     */
+    public static final class LaunchOptions {
+        private int xstart = 0;
+        private int ystart = 0;
+        private int xend = 0;
+        private int yend = 0;
+        private int zstart = 0;
+        private int zend = 0;
+        private int strategy;
+
+        /**
+         * Set the X range. xstartArg is the lowest coordinate of the range,
+         * and xendArg-1 is the highest coordinate of the range.
+         *
+         * @param xstartArg Must be >= 0
+         * @param xendArg Must be > xstartArg
+         *
+         * @return LaunchOptions
+         */
+        public LaunchOptions setX(int xstartArg, int xendArg) {
+            if (xstartArg < 0 || xendArg <= xstartArg) {
+                throw new RSIllegalArgumentException("Invalid dimensions");
+            }
+            xstart = xstartArg;
+            xend = xendArg;
+            return this;
+        }
+
+        /**
+         * Set the Y range. ystartArg is the lowest coordinate of the range,
+         * and yendArg-1 is the highest coordinate of the range.
+         *
+         * @param ystartArg Must be >= 0
+         * @param yendArg Must be > ystartArg
+         *
+         * @return LaunchOptions
+         */
+        public LaunchOptions setY(int ystartArg, int yendArg) {
+            if (ystartArg < 0 || yendArg <= ystartArg) {
+                throw new RSIllegalArgumentException("Invalid dimensions");
+            }
+            ystart = ystartArg;
+            yend = yendArg;
+            return this;
+        }
+
+        /**
+         * Set the Z range. zstartArg is the lowest coordinate of the range,
+         * and zendArg-1 is the highest coordinate of the range.
+         *
+         * @param zstartArg Must be >= 0
+         * @param zendArg Must be > zstartArg
+         *
+         * @return LaunchOptions
+         */
+        public LaunchOptions setZ(int zstartArg, int zendArg) {
+            if (zstartArg < 0 || zendArg <= zstartArg) {
+                throw new RSIllegalArgumentException("Invalid dimensions");
+            }
+            zstart = zstartArg;
+            zend = zendArg;
+            return this;
+        }
+
+
+        /**
+         * Returns the current X start
+         *
+         * @return int current value
+         */
+        public int getXStart() {
+            return xstart;
+        }
+        /**
+         * Returns the current X end
+         *
+         * @return int current value
+         */
+        public int getXEnd() {
+            return xend;
+        }
+        /**
+         * Returns the current Y start
+         *
+         * @return int current value
+         */
+        public int getYStart() {
+            return ystart;
+        }
+        /**
+         * Returns the current Y end
+         *
+         * @return int current value
+         */
+        public int getYEnd() {
+            return yend;
+        }
+        /**
+         * Returns the current Z start
+         *
+         * @return int current value
+         */
+        public int getZStart() {
+            return zstart;
+        }
+        /**
+         * Returns the current Z end
+         *
+         * @return int current value
+         */
+        public int getZEnd() {
+            return zend;
+        }
+
+    }
+}
diff --git a/androidx/renderscript/ScriptC.java b/androidx/renderscript/ScriptC.java
new file mode 100644
index 0000000..31201b1
--- /dev/null
+++ b/androidx/renderscript/ScriptC.java
@@ -0,0 +1,131 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map.Entry;
+import java.util.HashMap;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+/**
+ * The superclass for all user-defined scripts. This is only
+ * intended to be used by the generated derived classes.
+ **/
+public class ScriptC extends Script {
+    private static final String TAG = "ScriptC";
+
+    /**
+     * Only intended for use by the generated derived classes.
+     *
+     * @param id
+     * @param rs
+     */
+    protected ScriptC(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Only intended for use by the generated derived classes.
+     *
+     *
+     * @param rs
+     * @param resources
+     * @param resourceID
+     */
+    protected ScriptC(RenderScript rs, Resources resources, int resourceID) {
+        super(0, rs);
+        long id = internalCreate(rs, resources, resourceID);
+        if (id == 0) {
+            throw new RSRuntimeException("Loading of ScriptC script failed.");
+        }
+        setID(id);
+    }
+
+    /**
+     * Only intended for use by the generated derived classes.
+     *
+     * @param rs
+     * @param resName
+     * @param bitcode32
+     * @param bitcode64
+     */
+    protected ScriptC(RenderScript rs, String resName, byte[] bitcode32, byte[] bitcode64) {
+        super(0, rs);
+        long id = 0;
+        if (RenderScript.sPointerSize == 4) {
+            id = internalStringCreate(rs, resName, bitcode32);
+        } else {
+            id = internalStringCreate(rs, resName, bitcode64);
+        }
+        if (id == 0) {
+            throw new RSRuntimeException("Loading of ScriptC script failed.");
+        }
+        setID(id);
+    }
+
+    private static synchronized long internalCreate(RenderScript rs, Resources resources, int resourceID) {
+        byte[] pgm;
+        int pgmLength;
+        InputStream is = resources.openRawResource(resourceID);
+        try {
+            try {
+                pgm = new byte[1024];
+                pgmLength = 0;
+                while(true) {
+                    int bytesLeft = pgm.length - pgmLength;
+                    if (bytesLeft == 0) {
+                        byte[] buf2 = new byte[pgm.length * 2];
+                        System.arraycopy(pgm, 0, buf2, 0, pgm.length);
+                        pgm = buf2;
+                        bytesLeft = pgm.length - pgmLength;
+                    }
+                    int bytesRead = is.read(pgm, pgmLength, bytesLeft);
+                    if (bytesRead <= 0) {
+                        break;
+                    }
+                    pgmLength += bytesRead;
+                }
+            } finally {
+                is.close();
+            }
+        } catch(IOException e) {
+            throw new Resources.NotFoundException();
+        }
+
+        String resName = resources.getResourceEntryName(resourceID);
+        String cachePath = rs.getApplicationContext().getCacheDir().toString();
+
+        //        Log.v(TAG, "Create script for resource = " + resName + ", " + pgmLength + ", " + pgm);
+        //Log.v(TAG, " path = " + cachePath);
+        return rs.nScriptCCreate(resName, cachePath, pgm, pgmLength);
+    }
+
+    private static synchronized long internalStringCreate(RenderScript rs, String resName, byte[] bitcode) {
+        //        Log.v(TAG, "Create script for resource = " + resName);
+        String cachePath = rs.getApplicationContext().getCacheDir().toString();
+        return rs.nScriptCCreate(resName, cachePath, bitcode, bitcode.length);
+    }
+
+}
diff --git a/androidx/renderscript/ScriptGroup.java b/androidx/renderscript/ScriptGroup.java
new file mode 100644
index 0000000..ba8cf4b
--- /dev/null
+++ b/androidx/renderscript/ScriptGroup.java
@@ -0,0 +1,1180 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.util.Log;
+import android.util.Pair;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A group of kernels that are executed
+ * together with one execution call as if they were a single kernel
+ * <p>
+ * In addition to kernels, a script group may contain invocable functions as well.
+ * A script group may take inputs and generate outputs, which are consumed and
+ * produced by its member kernels.
+ * Inside a script group, outputs from one kernel can be passed to another kernel as inputs.
+ * The API disallows cyclic dependencies among kernels in a script group,
+ * effectively making it a directed acyclic graph (DAG) of kernels.
+ * <p>
+ * Grouping kernels together allows for more efficient execution. For example,
+ * runtime and compiler optimization can be applied to reduce computation and
+ * communication overhead, and to make better use of the CPU and the GPU.
+ **/
+public final class ScriptGroup extends BaseObj {
+    //FIXME: Change 23 to the codename when that is decided.
+    private static final int MIN_API_VERSION = 23;
+    private static final String TAG = "ScriptGroup";
+    IO mOutputs[];
+    IO mInputs[];
+    private boolean mUseIncSupp = false;
+    private ArrayList<Node> mNodes = new ArrayList<Node>();
+
+    static class IO {
+        Script.KernelID mKID;
+        Allocation mAllocation;
+
+        IO(Script.KernelID s) {
+            mKID = s;
+        }
+    }
+
+    static class ConnectLine {
+        ConnectLine(Type t, Script.KernelID from, Script.KernelID to) {
+            mFrom = from;
+            mToK = to;
+            mAllocationType = t;
+        }
+
+        ConnectLine(Type t, Script.KernelID from, Script.FieldID to) {
+            mFrom = from;
+            mToF = to;
+            mAllocationType = t;
+        }
+
+        Script.FieldID mToF;
+        Script.KernelID mToK;
+        Script.KernelID mFrom;
+        Type mAllocationType;
+        Allocation mAllocation;
+    }
+
+    static class Node {
+        Script mScript;
+        ArrayList<Script.KernelID> mKernels = new ArrayList<Script.KernelID>();
+        ArrayList<ConnectLine> mInputs = new ArrayList<ConnectLine>();
+        ArrayList<ConnectLine> mOutputs = new ArrayList<ConnectLine>();
+        int dagNumber;
+        boolean mSeen;
+        int mOrder;
+
+        Node mNext;
+
+        Node(Script s) {
+            mScript = s;
+        }
+    }
+
+    /**
+     * An opaque class for closures
+     * <p>
+     * A closure represents a function call to a kernel or invocable function,
+     * combined with arguments and values for global variables. A closure is
+     * created using the {@link Builder2#addKernel} or
+     * {@link Builder2#addInvoke}
+     * method.
+     */
+
+    public static final class Closure extends BaseObj {
+        private Object[] mArgs;
+        private Allocation mReturnValue;
+        private Map<Script.FieldID, Object> mBindings;
+
+        private Future mReturnFuture;
+        private Map<Script.FieldID, Future> mGlobalFuture;
+
+        private FieldPacker mFP;
+
+        private static final String TAG = "Closure";
+
+        Closure(long id, RenderScript rs) {
+            super(id, rs);
+        }
+
+        Closure(RenderScript rs, Script.KernelID kernelID, Type returnType,
+                       Object[] args, Map<Script.FieldID, Object> globals) {
+            super(0, rs);
+
+            if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
+                throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
+            }
+
+            mArgs = args;
+            mReturnValue = Allocation.createTyped(rs, returnType);
+            mBindings = globals;
+            mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+            int numValues = args.length + globals.size();
+
+            long[] fieldIDs = new long[numValues];
+            long[] values = new long[numValues];
+            int[] sizes = new int[numValues];
+            long[] depClosures = new long[numValues];
+            long[] depFieldIDs = new long[numValues];
+
+            int i;
+            for (i = 0; i < args.length; i++) {
+                fieldIDs[i] = 0;
+                retrieveValueAndDependenceInfo(rs, i, null, args[i],
+                                               values, sizes, depClosures, depFieldIDs);
+            }
+            for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+                Object obj = entry.getValue();
+                Script.FieldID fieldID = entry.getKey();
+                fieldIDs[i] = fieldID.getID(rs);
+                retrieveValueAndDependenceInfo(rs, i, fieldID, obj,
+                                               values, sizes, depClosures, depFieldIDs);
+                i++;
+            }
+
+            long id = rs.nClosureCreate(kernelID.getID(rs), mReturnValue.getID(rs),
+                                        fieldIDs, values, sizes, depClosures, depFieldIDs);
+
+            setID(id);
+        }
+
+        Closure(RenderScript rs, Script.InvokeID invokeID,
+                Object[] args, Map<Script.FieldID, Object> globals) {
+            super(0, rs);
+
+            if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
+                throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
+            }
+
+            mFP = FieldPacker.createFromArray(args);
+
+            mArgs = args;
+            mBindings = globals;
+            mGlobalFuture = new HashMap<Script.FieldID, Future>();
+
+            int numValues = globals.size();
+
+            long[] fieldIDs = new long[numValues];
+            long[] values = new long[numValues];
+            int[] sizes = new int[numValues];
+            long[] depClosures = new long[numValues];
+            long[] depFieldIDs = new long[numValues];
+
+            int i = 0;
+            for (Map.Entry<Script.FieldID, Object> entry : globals.entrySet()) {
+                Object obj = entry.getValue();
+                Script.FieldID fieldID = entry.getKey();
+                fieldIDs[i] = fieldID.getID(rs);
+                retrieveValueAndDependenceInfo(rs, i, fieldID, obj, values,
+                                               sizes, depClosures, depFieldIDs);
+                i++;
+            }
+
+            long id = rs.nInvokeClosureCreate(invokeID.getID(rs), mFP.getData(), fieldIDs,
+                                              values, sizes);
+
+            setID(id);
+        }
+
+        private void retrieveValueAndDependenceInfo(RenderScript rs,
+                                                    int index, Script.FieldID fid, Object obj,
+                                                    long[] values, int[] sizes,
+                                                    long[] depClosures,
+                                                    long[] depFieldIDs) {
+
+            if (obj instanceof Future) {
+                Future f = (Future)obj;
+                obj = f.getValue();
+                depClosures[index] = f.getClosure().getID(rs);
+                Script.FieldID fieldID = f.getFieldID();
+                depFieldIDs[index] = fieldID != null ? fieldID.getID(rs) : 0;
+            } else {
+                depClosures[index] = 0;
+                depFieldIDs[index] = 0;
+            }
+
+            if (obj instanceof Input) {
+                Input unbound = (Input)obj;
+                if (index < mArgs.length) {
+                    unbound.addReference(this, index);
+                } else {
+                    unbound.addReference(this, fid);
+                }
+                values[index] = 0;
+                sizes[index] = 0;
+            } else {
+                ValueAndSize vs = new ValueAndSize(rs, obj);
+                values[index] = vs.value;
+                sizes[index] = vs.size;
+            }
+        }
+
+        /**
+         * Returns the future for the return value
+         *
+         * @return a future
+         */
+
+        public Future getReturn() {
+            if (mReturnFuture == null) {
+                mReturnFuture = new Future(this, null, mReturnValue);
+            }
+
+            return mReturnFuture;
+        }
+
+        /**
+         * Returns the future for a global variable
+         *
+         * @param field the field ID for the global variable
+         * @return a future
+         */
+
+        public Future getGlobal(Script.FieldID field) {
+            Future f = mGlobalFuture.get(field);
+
+            if (f == null) {
+                // If the field is not bound to this closure, this will return a future
+                // without an associated value (reference). So this is not working for
+                // cross-module (cross-script) linking in this case where a field not
+                // explicitly bound.
+                Object obj = mBindings.get(field);
+                if (obj instanceof Future) {
+                    obj = ((Future)obj).getValue();
+                }
+                f = new Future(this, field, obj);
+                mGlobalFuture.put(field, f);
+            }
+
+            return f;
+        }
+
+        void setArg(int index, Object obj) {
+            if (obj instanceof Future) {
+                obj = ((Future)obj).getValue();
+            }
+            mArgs[index] = obj;
+            ValueAndSize vs = new ValueAndSize(mRS, obj);
+            mRS.nClosureSetArg(getID(mRS), index, vs.value, vs.size);
+        }
+
+        void setGlobal(Script.FieldID fieldID, Object obj) {
+            if (obj instanceof Future) {
+                obj = ((Future)obj).getValue();
+            }
+            mBindings.put(fieldID, obj);
+            ValueAndSize vs = new ValueAndSize(mRS, obj);
+            mRS.nClosureSetGlobal(getID(mRS), fieldID.getID(mRS), vs.value, vs.size);
+        }
+
+        private static final class ValueAndSize {
+            public ValueAndSize(RenderScript rs, Object obj) {
+                if (obj instanceof Allocation) {
+                    value = ((Allocation)obj).getID(rs);
+                    size = -1;
+                } else if (obj instanceof Boolean) {
+                    value = ((Boolean)obj).booleanValue() ? 1 : 0;
+                    size = 4;
+                } else if (obj instanceof Integer) {
+                    value = ((Integer)obj).longValue();
+                    size = 4;
+                } else if (obj instanceof Long) {
+                    value = ((Long)obj).longValue();
+                    size = 8;
+                } else if (obj instanceof Float) {
+                    value = Float.floatToRawIntBits(((Float)obj).floatValue());
+                    size = 4;
+                } else if (obj instanceof Double) {
+                    value = Double.doubleToRawLongBits(((Double)obj).doubleValue());
+                    size = 8;
+                }
+            }
+            public long value;
+            public int size;
+        }
+    }
+
+    /**
+     * An opaque class for futures
+     * <p>
+     * A future represents an output of a closure, either the return value of
+     * the function, or the value of a global variable written by the function.
+     * A future is created by calling the {@link Closure#getReturn}  or
+     * {@link Closure#getGlobal} method.
+     */
+
+    public static final class Future {
+        Closure mClosure;
+        Script.FieldID mFieldID;
+        Object mValue;
+
+        Future(Closure closure, Script.FieldID fieldID, Object value) {
+            mClosure = closure;
+            mFieldID = fieldID;
+            mValue = value;
+        }
+
+        Closure getClosure() { return mClosure; }
+        Script.FieldID getFieldID() { return mFieldID; }
+        Object getValue() { return mValue; }
+    }
+
+    /**
+     * An opaque class for unbound values (used for script group inputs)
+     * <p>
+     * Created by calling the {@link Builder2#addInput} method. The value
+     * is assigned in {@link ScriptGroup#execute(Object...)} method as
+     * one of its arguments. Arguments to the execute method should be in
+     * the same order as intputs are added using the addInput method.
+     */
+
+    public static final class Input {
+        // Either mFieldID or mArgIndex should be set but not both.
+        List<Pair<Closure, Script.FieldID>> mFieldID;
+        // -1 means unset. Legal values are 0 .. n-1, where n is the number of
+        // arguments for the referencing closure.
+        List<Pair<Closure, Integer>> mArgIndex;
+        Object mValue;
+
+        Input() {
+            mFieldID = new ArrayList<Pair<Closure, Script.FieldID>>();
+            mArgIndex = new ArrayList<Pair<Closure, Integer>>();
+        }
+
+        void addReference(Closure closure, int index) {
+            mArgIndex.add(Pair.create(closure, Integer.valueOf(index)));
+        }
+
+        void addReference(Closure closure, Script.FieldID fieldID) {
+            mFieldID.add(Pair.create(closure, fieldID));
+        }
+
+        void set(Object value) {
+            mValue = value;
+            for (Pair<Closure, Integer> p : mArgIndex) {
+                Closure closure = p.first;
+                int index = p.second.intValue();
+                closure.setArg(index, value);
+            }
+            for (Pair<Closure, Script.FieldID> p : mFieldID) {
+                Closure closure = p.first;
+                Script.FieldID fieldID = p.second;
+                closure.setGlobal(fieldID, value);
+            }
+        }
+
+        Object get() { return mValue; }
+    }
+
+    private String mName;
+    private List<Closure> mClosures;
+    private List<Input> mInputs2;
+    private Future[] mOutputs2;
+
+    ScriptGroup(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    ScriptGroup(RenderScript rs, String name, List<Closure> closures,
+                List<Input> inputs, Future[] outputs) {
+        super(0, rs);
+
+        if (android.os.Build.VERSION.SDK_INT < MIN_API_VERSION && rs.isUseNative()) {
+            throw new RSRuntimeException("ScriptGroup2 not supported in this API level");
+        }
+        mName = name;
+        mClosures = closures;
+        mInputs2 = inputs;
+        mOutputs2 = outputs;
+
+        long[] closureIDs = new long[closures.size()];
+        for (int i = 0; i < closureIDs.length; i++) {
+            closureIDs[i] = closures.get(i).getID(rs);
+        }
+        String cachePath = rs.getApplicationContext().getCacheDir().toString();
+        long id = rs.nScriptGroup2Create(name, cachePath, closureIDs);
+        setID(id);
+    }
+
+    /**
+     * Executes a script group
+     *
+     * @param inputs inputs to the script group
+     * @return outputs of the script group as an array of objects
+     */
+
+    public Object[] execute(Object... inputs) {
+        if (inputs.length < mInputs2.size()) {
+            Log.e(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+                  "less than expected " + mInputs2.size());
+            return null;
+        }
+
+        if (inputs.length > mInputs2.size()) {
+            Log.i(TAG, this.toString() + " receives " + inputs.length + " inputs, " +
+                  "more than expected " + mInputs2.size());
+        }
+
+        for (int i = 0; i < mInputs2.size(); i++) {
+            Object obj = inputs[i];
+            if (obj instanceof Future || obj instanceof Input) {
+                Log.e(TAG, this.toString() + ": input " + i +
+                      " is a future or unbound value");
+                return null;
+            }
+            Input unbound = mInputs2.get(i);
+            unbound.set(obj);
+        }
+
+        mRS.nScriptGroup2Execute(getID(mRS));
+
+        Object[] outputObjs = new Object[mOutputs2.length];
+        int i = 0;
+        for (Future f : mOutputs2) {
+            Object output = f.getValue();
+            if (output instanceof Input) {
+                output = ((Input)output).get();
+            }
+            outputObjs[i++] = output;
+        }
+        return outputObjs;
+    }
+
+    /**
+     * Sets an input of the ScriptGroup. This specifies an
+     * Allocation to be used for kernels that require an input
+     * Allocation provided from outside of the ScriptGroup.
+     *
+     * @deprecated Set arguments to {@link #execute(Object...)} instead.
+     *
+     * @param s The ID of the kernel where the allocation should be
+     *          connected.
+     * @param a The allocation to connect.
+     */
+    @Deprecated
+    public void setInput(Script.KernelID s, Allocation a) {
+        for (int ct=0; ct < mInputs.length; ct++) {
+            if (mInputs[ct].mKID == s) {
+                mInputs[ct].mAllocation = a;
+                if (!mUseIncSupp) {
+                    mRS.nScriptGroupSetInput(getID(mRS), s.getID(mRS), mRS.safeID(a));
+                }
+                return;
+            }
+        }
+        throw new RSIllegalArgumentException("Script not found");
+    }
+
+    /**
+     * Sets an output of the ScriptGroup. This specifies an
+     * Allocation to be used for the kernels that require an output
+     * Allocation visible after the ScriptGroup is executed.
+     *
+     * @deprecated Use return value of {@link #execute(Object...)} instead.
+     *
+     * @param s The ID of the kernel where the allocation should be
+     *          connected.
+     * @param a The allocation to connect.
+     */
+    @Deprecated
+    public void setOutput(Script.KernelID s, Allocation a) {
+        for (int ct=0; ct < mOutputs.length; ct++) {
+            if (mOutputs[ct].mKID == s) {
+                mOutputs[ct].mAllocation = a;
+                if (!mUseIncSupp) {
+                    mRS.nScriptGroupSetOutput(getID(mRS), s.getID(mRS), mRS.safeID(a));
+                }
+                return;
+            }
+        }
+        throw new RSIllegalArgumentException("Script not found");
+    }
+
+    /**
+     * Execute the ScriptGroup.  This will run all the kernels in
+     * the ScriptGroup.  No internal connection results will be visible
+     * after execution of the ScriptGroup.
+     *
+     * If Incremental Support for intrinsics is needed, the execution
+     * will take the naive path: execute kernels one by one in the
+     * correct order.
+     *
+     * @deprecated Use {@link #execute} instead.
+     */
+    @Deprecated
+    public void execute() {
+        if (!mUseIncSupp) {
+            mRS.nScriptGroupExecute(getID(mRS));
+        } else {
+            // setup the allocations.
+            for (int ct=0; ct < mNodes.size(); ct++) {
+                Node n = mNodes.get(ct);
+                for (int ct2=0; ct2 < n.mOutputs.size(); ct2++) {
+                    ConnectLine l = n.mOutputs.get(ct2);
+                    if (l.mAllocation !=null) {
+                        continue;
+                    }
+
+                    //create allocation here
+                    Allocation alloc = Allocation.createTyped(mRS, l.mAllocationType,
+                                                              Allocation.MipmapControl.MIPMAP_NONE,
+                                                              Allocation.USAGE_SCRIPT);
+
+                    l.mAllocation = alloc;
+                    for (int ct3=ct2+1; ct3 < n.mOutputs.size(); ct3++) {
+                        if (n.mOutputs.get(ct3).mFrom == l.mFrom) {
+                            n.mOutputs.get(ct3).mAllocation = alloc;
+                        }
+                    }
+                }
+            }
+            for (Node node : mNodes) {
+                for (Script.KernelID kernel : node.mKernels) {
+                    Allocation ain  = null;
+                    Allocation aout = null;
+
+                    for (ConnectLine nodeInput : node.mInputs) {
+                        if (nodeInput.mToK == kernel) {
+                            ain = nodeInput.mAllocation;
+                        }
+                    }
+
+                    for (IO sgInput : mInputs) {
+                        if (sgInput.mKID == kernel) {
+                            ain = sgInput.mAllocation;
+                        }
+                    }
+
+                    for (ConnectLine nodeOutput : node.mOutputs) {
+                        if (nodeOutput.mFrom == kernel) {
+                            aout = nodeOutput.mAllocation;
+                        }
+                    }
+
+                    for (IO sgOutput : mOutputs) {
+                        if (sgOutput.mKID == kernel) {
+                            aout = sgOutput.mAllocation;
+                        }
+                    }
+
+                    kernel.mScript.forEach(kernel.mSlot, ain, aout, null);
+                }
+            }
+        }
+    }
+
+
+    /**
+     * Helper class to build a ScriptGroup. A ScriptGroup is
+     * created in two steps.
+     * <p>
+     * First, all kernels to be used by the ScriptGroup should be added.
+     * <p>
+     * Second, add connections between kernels. There are two types
+     * of connections: kernel to kernel and kernel to field.
+     * Kernel to kernel allows a kernel's output to be passed to
+     * another kernel as input. Kernel to field allows the output of
+     * one kernel to be bound as a script global. Kernel to kernel is
+     * higher performance and should be used where possible.
+     * <p>
+     * A ScriptGroup must contain a single directed acyclic graph (DAG); it
+     * cannot contain cycles. Currently, all kernels used in a ScriptGroup
+     * must come from different Script objects. Additionally, all kernels
+     * in a ScriptGroup must have at least one input, output, or internal
+     * connection.
+     * <p>
+     * Once all connections are made, a call to {@link #create} will
+     * return the ScriptGroup object.
+     *
+     * @deprecated Use {@link Builder2} instead.
+     *
+     */
+    @Deprecated
+    public static final class Builder {
+        private RenderScript mRS;
+        private ArrayList<Node> mNodes = new ArrayList<Node>();
+        private ArrayList<ConnectLine> mLines = new ArrayList<ConnectLine>();
+        private int mKernelCount;
+        private boolean mUseIncSupp = false;
+
+        /**
+         * Create a Builder for generating a ScriptGroup.
+         *
+         *
+         * @param rs The RenderScript context.
+         */
+        public Builder(RenderScript rs) {
+            mRS = rs;
+        }
+
+        // do a DFS from original node, looking for original node
+        // any cycle that could be created must contain original node
+        private void validateCycle(Node target, Node original) {
+            for (int ct = 0; ct < target.mOutputs.size(); ct++) {
+                final ConnectLine cl = target.mOutputs.get(ct);
+                if (cl.mToK != null) {
+                    Node tn = findNode(cl.mToK.mScript);
+                    if (tn.equals(original)) {
+                        throw new RSInvalidStateException("Loops in group not allowed.");
+                    }
+                    validateCycle(tn, original);
+                }
+                if (cl.mToF != null) {
+                    Node tn = findNode(cl.mToF.mScript);
+                    if (tn.equals(original)) {
+                        throw new RSInvalidStateException("Loops in group not allowed.");
+                    }
+                    validateCycle(tn, original);
+                }
+            }
+        }
+
+        private void mergeDAGs(int valueUsed, int valueKilled) {
+            for (int ct=0; ct < mNodes.size(); ct++) {
+                if (mNodes.get(ct).dagNumber == valueKilled)
+                    mNodes.get(ct).dagNumber = valueUsed;
+            }
+        }
+
+        private void validateDAGRecurse(Node n, int dagNumber) {
+            // combine DAGs if this node has been seen already
+            if (n.dagNumber != 0 && n.dagNumber != dagNumber) {
+                mergeDAGs(n.dagNumber, dagNumber);
+                return;
+            }
+
+            n.dagNumber = dagNumber;
+            for (int ct=0; ct < n.mOutputs.size(); ct++) {
+                final ConnectLine cl = n.mOutputs.get(ct);
+                if (cl.mToK != null) {
+                    Node tn = findNode(cl.mToK.mScript);
+                    validateDAGRecurse(tn, dagNumber);
+                }
+                if (cl.mToF != null) {
+                    Node tn = findNode(cl.mToF.mScript);
+                    validateDAGRecurse(tn, dagNumber);
+                }
+            }
+        }
+
+        private void validateDAG() {
+            for (int ct=0; ct < mNodes.size(); ct++) {
+                Node n = mNodes.get(ct);
+                if (n.mInputs.size() == 0) {
+                    if (n.mOutputs.size() == 0 && mNodes.size() > 1) {
+                        String msg = "Groups cannot contain unconnected scripts";
+                        throw new RSInvalidStateException(msg);
+                    }
+                    validateDAGRecurse(n, ct+1);
+                }
+            }
+            int dagNumber = mNodes.get(0).dagNumber;
+            for (int ct=0; ct < mNodes.size(); ct++) {
+                if (mNodes.get(ct).dagNumber != dagNumber) {
+                    throw new RSInvalidStateException("Multiple DAGs in group not allowed.");
+                }
+            }
+        }
+
+        private Node findNode(Script s) {
+            for (int ct=0; ct < mNodes.size(); ct++) {
+                if (s == mNodes.get(ct).mScript) {
+                    return mNodes.get(ct);
+                }
+            }
+            return null;
+        }
+
+        private Node findNode(Script.KernelID k) {
+            for (int ct=0; ct < mNodes.size(); ct++) {
+                Node n = mNodes.get(ct);
+                for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
+                    if (k == n.mKernels.get(ct2)) {
+                        return n;
+                    }
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Adds a Kernel to the group.
+         *
+         *
+         * @param k The kernel to add.
+         *
+         * @return Builder Returns this.
+         */
+        public Builder addKernel(Script.KernelID k) {
+            if (mLines.size() != 0) {
+                throw new RSInvalidStateException(
+                    "Kernels may not be added once connections exist.");
+            }
+            if (k.mScript.isIncSupp()) {
+                mUseIncSupp = true;
+            }
+            //android.util.Log.v("RSR", "addKernel 1 k=" + k);
+            if (findNode(k) != null) {
+                return this;
+            }
+            //android.util.Log.v("RSR", "addKernel 2 ");
+            mKernelCount++;
+            Node n = findNode(k.mScript);
+            if (n == null) {
+                //android.util.Log.v("RSR", "addKernel 3 ");
+                n = new Node(k.mScript);
+                mNodes.add(n);
+            }
+            n.mKernels.add(k);
+            return this;
+        }
+
+        /**
+         * Adds a connection to the group.
+         *
+         *
+         * @param t The type of the connection. This is used to
+         *          determine the kernel launch sizes on the source side
+         *          of this connection.
+         * @param from The source for the connection.
+         * @param to The destination of the connection.
+         *
+         * @return Builder Returns this
+         */
+        public Builder addConnection(Type t, Script.KernelID from, Script.FieldID to) {
+            //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to);
+            Node nf = findNode(from);
+            if (nf == null) {
+                throw new RSInvalidStateException("From script not found.");
+            }
+
+            Node nt = findNode(to.mScript);
+            if (nt == null) {
+                throw new RSInvalidStateException("To script not found.");
+            }
+
+            ConnectLine cl = new ConnectLine(t, from, to);
+            mLines.add(new ConnectLine(t, from, to));
+
+            nf.mOutputs.add(cl);
+            nt.mInputs.add(cl);
+
+            validateCycle(nf, nf);
+            return this;
+        }
+
+        /**
+         * Adds a connection to the group.
+         *
+         *
+         * @param t The type of the connection. This is used to
+         *          determine the kernel launch sizes for both sides of
+         *          this connection.
+         * @param from The source for the connection.
+         * @param to The destination of the connection.
+         *
+         * @return Builder Returns this
+         */
+        public Builder addConnection(Type t, Script.KernelID from, Script.KernelID to) {
+            //android.util.Log.v("RSR", "addConnection " + t +", " + from + ", " + to);
+            Node nf = findNode(from);
+            if (nf == null) {
+                throw new RSInvalidStateException("From script not found.");
+            }
+
+            Node nt = findNode(to);
+            if (nt == null) {
+                throw new RSInvalidStateException("To script not found.");
+            }
+
+            ConnectLine cl = new ConnectLine(t, from, to);
+            mLines.add(new ConnectLine(t, from, to));
+
+            nf.mOutputs.add(cl);
+            nt.mInputs.add(cl);
+
+            validateCycle(nf, nf);
+            return this;
+        }
+
+        /**
+         * Calculate the order of each node.
+         *
+         *
+         * @return Success or Fail
+         */
+        private boolean calcOrderRecurse(Node node0, int depth) {
+            node0.mSeen = true;
+            if (node0.mOrder < depth) {
+                node0.mOrder = depth;
+            }
+            boolean ret = true;
+
+            for (ConnectLine link : node0.mOutputs) {
+                Node node1 = null;
+                if (link.mToF != null) {
+                    node1 = findNode(link.mToF.mScript);
+                } else {
+                    node1 = findNode(link.mToK.mScript);
+                }
+                if (node1.mSeen) {
+                    return false;
+                }
+                ret &= calcOrderRecurse(node1, node0.mOrder + 1);
+            }
+
+            return ret;
+        }
+
+        private boolean calcOrder() {
+            boolean ret = true;
+            for (Node n0 : mNodes) {
+                if (n0.mInputs.size() == 0) {
+                    for (Node n1 : mNodes) {
+                        n1.mSeen = false;
+                    }
+                    ret &= calcOrderRecurse(n0, 1);
+                }
+            }
+
+            Collections.sort(mNodes, new Comparator<Node>() {
+                public int compare(Node n1, Node n2) {
+                    return n1.mOrder - n2.mOrder;
+                }
+            });
+
+            return ret;
+        }
+
+        /**
+         * Creates the Script group.
+         *
+         *
+         * @return ScriptGroup The new ScriptGroup
+         */
+        public ScriptGroup create() {
+
+            if (mNodes.size() == 0) {
+                throw new RSInvalidStateException("Empty script groups are not allowed");
+            }
+
+            // reset DAG numbers in case we're building a second group
+            for (int ct=0; ct < mNodes.size(); ct++) {
+                mNodes.get(ct).dagNumber = 0;
+            }
+            validateDAG();
+
+            ArrayList<IO> inputs = new ArrayList<IO>();
+            ArrayList<IO> outputs = new ArrayList<IO>();
+
+            long[] kernels = new long[mKernelCount];
+            int idx = 0;
+            for (int ct=0; ct < mNodes.size(); ct++) {
+                Node n = mNodes.get(ct);
+                for (int ct2=0; ct2 < n.mKernels.size(); ct2++) {
+                    final Script.KernelID kid = n.mKernels.get(ct2);
+                    kernels[idx++] = kid.getID(mRS);
+
+                    boolean hasInput = false;
+                    boolean hasOutput = false;
+                    for (int ct3=0; ct3 < n.mInputs.size(); ct3++) {
+                        if (n.mInputs.get(ct3).mToK == kid) {
+                            hasInput = true;
+                        }
+                    }
+                    for (int ct3=0; ct3 < n.mOutputs.size(); ct3++) {
+                        if (n.mOutputs.get(ct3).mFrom == kid) {
+                            hasOutput = true;
+                        }
+                    }
+                    if (!hasInput) {
+                        inputs.add(new IO(kid));
+                    }
+                    if (!hasOutput) {
+                        outputs.add(new IO(kid));
+                    }
+                }
+            }
+            if (idx != mKernelCount) {
+                throw new RSRuntimeException("Count mismatch, should not happen.");
+            }
+
+            long id = 0;
+            if (!mUseIncSupp) {
+                long[] src = new long[mLines.size()];
+                long[] dstk = new long[mLines.size()];
+                long[] dstf = new long[mLines.size()];
+                long[] types = new long[mLines.size()];
+
+                for (int ct=0; ct < mLines.size(); ct++) {
+                    ConnectLine cl = mLines.get(ct);
+                    src[ct] = cl.mFrom.getID(mRS);
+                    if (cl.mToK != null) {
+                        dstk[ct] = cl.mToK.getID(mRS);
+                    }
+                    if (cl.mToF != null) {
+                        dstf[ct] = cl.mToF.getID(mRS);
+                    }
+                    types[ct] = cl.mAllocationType.getID(mRS);
+                }
+                id = mRS.nScriptGroupCreate(kernels, src, dstk, dstf, types);
+                if (id == 0) {
+                    throw new RSRuntimeException("Object creation error, should not happen.");
+                }
+            } else {
+                //Calculate the order of the DAG so that script can run one after another.
+                calcOrder();
+            }
+
+            ScriptGroup sg = new ScriptGroup(id, mRS);
+            sg.mOutputs = new IO[outputs.size()];
+            for (int ct=0; ct < outputs.size(); ct++) {
+                sg.mOutputs[ct] = outputs.get(ct);
+            }
+
+            sg.mInputs = new IO[inputs.size()];
+            for (int ct=0; ct < inputs.size(); ct++) {
+                sg.mInputs[ct] = inputs.get(ct);
+            }
+            sg.mNodes = mNodes;
+            sg.mUseIncSupp = mUseIncSupp;
+            return sg;
+        }
+
+    }
+
+    /**
+     * Represents a binding of a value to a global variable in a
+     * kernel or invocable function. Used in closure creation.
+     */
+
+    public static final class Binding {
+        private final Script.FieldID mField;
+        private final Object mValue;
+
+        /**
+         * Returns a Binding object that binds value to field
+         *
+         * @param field the Script.FieldID of the global variable
+         * @param value the value
+         */
+
+        public Binding(Script.FieldID field, Object value) {
+            mField = field;
+            mValue = value;
+        }
+
+        /**
+         * Returns the field ID
+         */
+
+        public Script.FieldID getField() { return mField; }
+
+        /**
+         * Returns the value
+         */
+
+        public Object getValue() { return mValue; }
+    }
+
+    /**
+     * The builder class for creating script groups
+     * <p>
+     * A script group is created using closures (see class {@link Closure}).
+     * A closure is a function call to a kernel or
+     * invocable function. Each function argument or global variable accessed inside
+     * the function is bound to 1) a known value, 2) a script group input
+     * (see class {@link Input}), or 3) a
+     * future (see class {@link Future}).
+     * A future is the output of a closure, either the return value of the
+     * function or a global variable written by that function.
+     * <p>
+     * Closures are created using the {@link #addKernel} or {@link #addInvoke}
+     * methods.
+     * When a closure is created, futures from previously created closures
+     * can be used as its inputs.
+     * External script group inputs can be used as inputs to individual closures as well.
+     * An external script group input is created using the {@link #addInput} method.
+     * A script group is created by a call to the {@link #create} method, which
+     * accepts an array of futures as the outputs for the script group.
+     * <p>
+     * Closures in a script group can be evaluated in any order as long as the
+     * following conditions are met:
+     * 1) a closure must be evaluated before any other closures that take its
+     * futures as inputs;
+     * 2) all closures added before an invoke closure must be evaluated
+     * before it;
+     * and 3) all closures added after an invoke closure must be evaluated after
+     * it.
+     * As a special case, the order that the closures are added is a legal
+     * evaluation order. However, other evaluation orders are possible, including
+     * concurrently evaluating independent closures.
+     */
+
+    public static final class Builder2 {
+        RenderScript mRS;
+        List<Closure> mClosures;
+        List<Input> mInputs;
+        private static final String TAG = "ScriptGroup.Builder2";
+
+        /**
+         * Returns a Builder object
+         *
+         * @param rs the RenderScript context
+         */
+        public Builder2(RenderScript rs) {
+            mRS = rs;
+            mClosures = new ArrayList<Closure>();
+            mInputs = new ArrayList<Input>();
+        }
+
+        /**
+         * Adds a closure for a kernel
+         *
+         * @param k Kernel ID for the kernel function
+         * @param returnType Allocation type for the return value
+         * @param args arguments to the kernel function
+         * @param globalBindings bindings for global variables
+         * @return a closure
+         */
+
+        private Closure addKernelInternal(Script.KernelID k, Type returnType, Object[] args,
+                                          Map<Script.FieldID, Object> globalBindings) {
+            Closure c = new Closure(mRS, k, returnType, args, globalBindings);
+            mClosures.add(c);
+            return c;
+        }
+
+        /**
+         * Adds a closure for an invocable function
+         *
+         * @param invoke Invoke ID for the invocable function
+         * @param args arguments to the invocable function
+         * @param globalBindings bindings for global variables
+         * @return a closure
+         */
+
+        private Closure addInvokeInternal(Script.InvokeID invoke, Object[] args,
+                                          Map<Script.FieldID, Object> globalBindings) {
+            Closure c = new Closure(mRS, invoke, args, globalBindings);
+            mClosures.add(c);
+            return c;
+        }
+
+        /**
+         * Adds a script group input
+         *
+         * @return a script group input, which can be used as an argument or a value to
+         *     a global variable for creating closures
+         */
+
+        public Input addInput() {
+            Input unbound = new Input();
+            mInputs.add(unbound);
+            return unbound;
+        }
+
+        /**
+         * Adds a closure for a kernel
+         *
+         * @param k Kernel ID for the kernel function
+         * @param argsAndBindings arguments followed by bindings for global variables
+         * @return a closure
+         */
+
+        public Closure addKernel(Script.KernelID k, Type returnType, Object... argsAndBindings) {
+            ArrayList<Object> args = new ArrayList<Object>();
+            Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+            if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+                return null;
+            }
+            return addKernelInternal(k, returnType, args.toArray(), bindingMap);
+        }
+
+        /**
+         * Adds a closure for an invocable function
+         *
+         * @param invoke Invoke ID for the invocable function
+         * @param argsAndBindings arguments followed by bindings for global variables
+         * @return a closure
+         */
+
+        public Closure addInvoke(Script.InvokeID invoke, Object... argsAndBindings) {
+            ArrayList<Object> args = new ArrayList<Object>();
+            Map<Script.FieldID, Object> bindingMap = new HashMap<Script.FieldID, Object>();
+            if (!seperateArgsAndBindings(argsAndBindings, args, bindingMap)) {
+                return null;
+            }
+            return addInvokeInternal(invoke, args.toArray(), bindingMap);
+        }
+
+        /**
+         * Creates a script group
+         *
+         * @param name name for the script group. Legal names can only contain letters, digits,
+         *        '-', or '_'. The name can be no longer than 100 characters.
+         * @param outputs futures intended as outputs of the script group
+         * @return a script group
+         */
+
+        public ScriptGroup create(String name, Future... outputs) {
+            if (name == null || name.isEmpty() || name.length() > 100 ||
+                !name.equals(name.replaceAll("[^a-zA-Z0-9-]", "_"))) {
+                throw new RSIllegalArgumentException("invalid script group name");
+            }
+            ScriptGroup ret = new ScriptGroup(mRS, name, mClosures, mInputs, outputs);
+            return ret;
+        }
+
+        private boolean seperateArgsAndBindings(Object[] argsAndBindings,
+                                                ArrayList<Object> args,
+                                                Map<Script.FieldID, Object> bindingMap) {
+            int i;
+            for (i = 0; i < argsAndBindings.length; i++) {
+                if (argsAndBindings[i] instanceof Binding) {
+                    break;
+                }
+                args.add(argsAndBindings[i]);
+            }
+
+            for (; i < argsAndBindings.length; i++) {
+                if (!(argsAndBindings[i] instanceof Binding)) {
+                    return false;
+                }
+                Binding b = (Binding)argsAndBindings[i];
+                bindingMap.put(b.getField(), b.getValue());
+            }
+
+            return true;
+        }
+
+    }
+
+}
+
+
diff --git a/androidx/renderscript/ScriptIntrinsic.java b/androidx/renderscript/ScriptIntrinsic.java
new file mode 100644
index 0000000..cf7b72e
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsic.java
@@ -0,0 +1,34 @@
+/*
+ * 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 androidx.renderscript;
+
+/**
+ * Base class for all Intrinsic scripts. An intrinsic a script
+ * which implements a pre-defined function. Intrinsics are
+ * provided to provide effecient implemtations of common
+ * operations.
+ *
+ * Not intended for direct use.
+ **/
+public abstract class ScriptIntrinsic extends Script {
+    ScriptIntrinsic(long id, RenderScript rs) {
+        super(id, rs);
+        if (id == 0) {
+            throw new RSRuntimeException("Loading of ScriptIntrinsic failed.");
+        }
+    }
+}
diff --git a/androidx/renderscript/ScriptIntrinsic3DLUT.java b/androidx/renderscript/ScriptIntrinsic3DLUT.java
new file mode 100644
index 0000000..e7b6a07
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsic3DLUT.java
@@ -0,0 +1,110 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ *
+ * Intrinsic for converting RGB to RGBA by using a 3D lookup table.  The
+ * incoming r,g,b values are use as normalized x,y,z coordinates into a 3D
+ * allocation.  The 8 nearest values are sampled and linearly interpolated.  The
+ * result is placed in the output.
+ *
+ **/
+public class ScriptIntrinsic3DLUT extends ScriptIntrinsic {
+    private Allocation mLUT;
+    private Element mElement;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    protected ScriptIntrinsic3DLUT(long id, RenderScript rs, Element e) {
+        super(id, rs);
+        mElement = e;
+    }
+
+    /**
+     * Supported elements types are {@link Element#U8_4}
+     *
+     * The defaults tables are identity.
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for intputs and outputs
+     *
+     * @return ScriptIntrinsic3DLUT
+     */
+    public static ScriptIntrinsic3DLUT create(RenderScript rs, Element e) {
+        if (!e.isCompatible(Element.U8_4(rs))) {
+            throw new RSIllegalArgumentException("Element must be compatible with uchar4.");
+        }
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(8, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsic3DLUT si = new ScriptIntrinsic3DLUT(id, rs, e);
+        si.setIncSupp(mUseIncSupp);
+        return si;
+    }
+
+    /**
+     * Sets the {@link androidx.renderscript.Allocation} to be used as
+     * the lookup table.
+     *
+     * The lookup table must use the same
+     * {@link androidx.renderscript.Element} as the intrinsic.
+     *
+     */
+
+    public void setLUT(Allocation lut) {
+        final Type t = lut.getType();
+
+        if (t.getZ() == 0) {
+            throw new RSIllegalArgumentException("LUT must be 3d.");
+        }
+
+        if (!t.getElement().isCompatible(mElement)) {
+            throw new RSIllegalArgumentException("LUT element type must match.");
+        }
+
+        mLUT = lut;
+        setVar(0, mLUT);
+    }
+
+
+    /**
+     * Invoke the kernel and apply the lookup to each cell of ain
+     * and copy to aout.
+     *
+     * @param ain Input allocation
+     * @param aout Output allocation
+     */
+    public void forEach(Allocation ain, Allocation aout) {
+        forEach(0, ain, aout, null);
+    }
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID() {
+        return createKernelID(0, 3, null, null);
+    }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicBLAS.java b/androidx/renderscript/ScriptIntrinsicBLAS.java
new file mode 100644
index 0000000..7d8e668
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicBLAS.java
@@ -0,0 +1,4190 @@
+/*
+ * Copyright (C) 2015 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 androidx.renderscript;
+
+import android.support.annotation.IntDef;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ *
+ * ScriptIntrinsicBLAS class provides high performance RenderScript APIs to BLAS.
+ *
+ * The BLAS (Basic Linear Algebra Subprograms) are routines that provide standard
+ * building blocks for performing basic vector and matrix operations.
+ *
+ * For detailed description of BLAS, please refer to http://www.netlib.org/blas/
+ *
+ **/
+public final class ScriptIntrinsicBLAS extends ScriptIntrinsic {
+    private Allocation mLUT;
+    private static final int INTRINSIC_API_LEVEL = 23;
+
+    private ScriptIntrinsicBLAS(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    private static final int RsBlas_sdsdot = 1;
+    private static final int RsBlas_dsdot = 2;
+    private static final int RsBlas_sdot = 3;
+    private static final int RsBlas_ddot = 4;
+    private static final int RsBlas_cdotu_sub = 5;
+    private static final int RsBlas_cdotc_sub = 6;
+    private static final int RsBlas_zdotu_sub = 7;
+    private static final int RsBlas_zdotc_sub = 8;
+    private static final int RsBlas_snrm2 = 9;
+    private static final int RsBlas_sasum = 10;
+    private static final int RsBlas_dnrm2 = 11;
+    private static final int RsBlas_dasum = 12;
+    private static final int RsBlas_scnrm2 = 13;
+    private static final int RsBlas_scasum = 14;
+    private static final int RsBlas_dznrm2 = 15;
+    private static final int RsBlas_dzasum = 16;
+    private static final int RsBlas_isamax = 17;
+    private static final int RsBlas_idamax = 18;
+    private static final int RsBlas_icamax = 19;
+    private static final int RsBlas_izamax = 20;
+    private static final int RsBlas_sswap = 21;
+    private static final int RsBlas_scopy = 22;
+    private static final int RsBlas_saxpy = 23;
+    private static final int RsBlas_dswap = 24;
+    private static final int RsBlas_dcopy = 25;
+    private static final int RsBlas_daxpy = 26;
+    private static final int RsBlas_cswap = 27;
+    private static final int RsBlas_ccopy = 28;
+    private static final int RsBlas_caxpy = 29;
+    private static final int RsBlas_zswap = 30;
+    private static final int RsBlas_zcopy = 31;
+    private static final int RsBlas_zaxpy = 32;
+    private static final int RsBlas_srotg = 33;
+    private static final int RsBlas_srotmg = 34;
+    private static final int RsBlas_srot = 35;
+    private static final int RsBlas_srotm = 36;
+    private static final int RsBlas_drotg = 37;
+    private static final int RsBlas_drotmg = 38;
+    private static final int RsBlas_drot = 39;
+    private static final int RsBlas_drotm = 40;
+    private static final int RsBlas_sscal = 41;
+    private static final int RsBlas_dscal = 42;
+    private static final int RsBlas_cscal = 43;
+    private static final int RsBlas_zscal = 44;
+    private static final int RsBlas_csscal = 45;
+    private static final int RsBlas_zdscal = 46;
+    private static final int RsBlas_sgemv = 47;
+    private static final int RsBlas_sgbmv = 48;
+    private static final int RsBlas_strmv = 49;
+    private static final int RsBlas_stbmv = 50;
+    private static final int RsBlas_stpmv = 51;
+    private static final int RsBlas_strsv = 52;
+    private static final int RsBlas_stbsv = 53;
+    private static final int RsBlas_stpsv = 54;
+    private static final int RsBlas_dgemv = 55;
+    private static final int RsBlas_dgbmv = 56;
+    private static final int RsBlas_dtrmv = 57;
+    private static final int RsBlas_dtbmv = 58;
+    private static final int RsBlas_dtpmv = 59;
+    private static final int RsBlas_dtrsv = 60;
+    private static final int RsBlas_dtbsv = 61;
+    private static final int RsBlas_dtpsv = 62;
+    private static final int RsBlas_cgemv = 63;
+    private static final int RsBlas_cgbmv = 64;
+    private static final int RsBlas_ctrmv = 65;
+    private static final int RsBlas_ctbmv = 66;
+    private static final int RsBlas_ctpmv = 67;
+    private static final int RsBlas_ctrsv = 68;
+    private static final int RsBlas_ctbsv = 69;
+    private static final int RsBlas_ctpsv = 70;
+    private static final int RsBlas_zgemv = 71;
+    private static final int RsBlas_zgbmv = 72;
+    private static final int RsBlas_ztrmv = 73;
+    private static final int RsBlas_ztbmv = 74;
+    private static final int RsBlas_ztpmv = 75;
+    private static final int RsBlas_ztrsv = 76;
+    private static final int RsBlas_ztbsv = 77;
+    private static final int RsBlas_ztpsv = 78;
+    private static final int RsBlas_ssymv = 79;
+    private static final int RsBlas_ssbmv = 80;
+    private static final int RsBlas_sspmv = 81;
+    private static final int RsBlas_sger = 82;
+    private static final int RsBlas_ssyr = 83;
+    private static final int RsBlas_sspr = 84;
+    private static final int RsBlas_ssyr2 = 85;
+    private static final int RsBlas_sspr2 = 86;
+    private static final int RsBlas_dsymv = 87;
+    private static final int RsBlas_dsbmv = 88;
+    private static final int RsBlas_dspmv = 89;
+    private static final int RsBlas_dger = 90;
+    private static final int RsBlas_dsyr = 91;
+    private static final int RsBlas_dspr = 92;
+    private static final int RsBlas_dsyr2 = 93;
+    private static final int RsBlas_dspr2 = 94;
+    private static final int RsBlas_chemv = 95;
+    private static final int RsBlas_chbmv = 96;
+    private static final int RsBlas_chpmv = 97;
+    private static final int RsBlas_cgeru = 98;
+    private static final int RsBlas_cgerc = 99;
+    private static final int RsBlas_cher = 100;
+    private static final int RsBlas_chpr = 101;
+    private static final int RsBlas_cher2 = 102;
+    private static final int RsBlas_chpr2 = 103;
+    private static final int RsBlas_zhemv = 104;
+    private static final int RsBlas_zhbmv = 105;
+    private static final int RsBlas_zhpmv = 106;
+    private static final int RsBlas_zgeru = 107;
+    private static final int RsBlas_zgerc = 108;
+    private static final int RsBlas_zher = 109;
+    private static final int RsBlas_zhpr = 110;
+    private static final int RsBlas_zher2 = 111;
+    private static final int RsBlas_zhpr2 = 112;
+    private static final int RsBlas_sgemm = 113;
+    private static final int RsBlas_ssymm = 114;
+    private static final int RsBlas_ssyrk = 115;
+    private static final int RsBlas_ssyr2k = 116;
+    private static final int RsBlas_strmm = 117;
+    private static final int RsBlas_strsm = 118;
+    private static final int RsBlas_dgemm = 119;
+    private static final int RsBlas_dsymm = 120;
+    private static final int RsBlas_dsyrk = 121;
+    private static final int RsBlas_dsyr2k = 122;
+    private static final int RsBlas_dtrmm = 123;
+    private static final int RsBlas_dtrsm = 124;
+    private static final int RsBlas_cgemm = 125;
+    private static final int RsBlas_csymm = 126;
+    private static final int RsBlas_csyrk = 127;
+    private static final int RsBlas_csyr2k = 128;
+    private static final int RsBlas_ctrmm = 129;
+    private static final int RsBlas_ctrsm = 130;
+    private static final int RsBlas_zgemm = 131;
+    private static final int RsBlas_zsymm = 132;
+    private static final int RsBlas_zsyrk = 133;
+    private static final int RsBlas_zsyr2k = 134;
+    private static final int RsBlas_ztrmm = 135;
+    private static final int RsBlas_ztrsm = 136;
+    private static final int RsBlas_chemm = 137;
+    private static final int RsBlas_cherk = 138;
+    private static final int RsBlas_cher2k = 139;
+    private static final int RsBlas_zhemm = 140;
+    private static final int RsBlas_zherk = 141;
+    private static final int RsBlas_zher2k = 142;
+
+    // BLAS extensions start here
+    private static final int RsBlas_bnnm = 1000;
+
+    /**
+     * Create an intrinsic to access BLAS subroutines.
+     *
+     * @param rs The RenderScript context
+     * @return ScriptIntrinsicBLAS
+     */
+    public static ScriptIntrinsicBLAS create(RenderScript rs) {
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(13, Element.U32(rs).getID(rs), mUseIncSupp);
+        ScriptIntrinsicBLAS si = new ScriptIntrinsicBLAS(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        return si;
+    }
+
+    /**
+     * @hide
+     */
+    @IntDef({NO_TRANSPOSE, TRANSPOSE, CONJ_TRANSPOSE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Transpose {}
+
+    /**
+     * @hide
+     */
+    @IntDef({UPPER, LOWER})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Uplo {}
+
+    /**
+     * @hide
+     */
+    @IntDef({NON_UNIT, UNIT})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Diag {}
+
+    /**
+     * @hide
+     */
+    @IntDef({LEFT, RIGHT})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Side {}
+
+    public static final int NO_TRANSPOSE = 111;
+    public static final int TRANSPOSE = 112;
+    public static final int CONJ_TRANSPOSE = 113;
+
+    public static final int UPPER = 121;
+    public static final int LOWER = 122;
+
+    public static final int NON_UNIT = 131;
+    public static final int UNIT = 132;
+
+    public static final int LEFT = 141;
+    public static final int RIGHT = 142;
+
+    static void validateSide(@Side int Side) {
+        if (Side != LEFT && Side != RIGHT) {
+            throw new RSRuntimeException("Invalid side passed to BLAS");
+        }
+    }
+
+    static void validateTranspose(@Transpose int Trans) {
+        if (Trans != NO_TRANSPOSE && Trans != TRANSPOSE &&
+            Trans != CONJ_TRANSPOSE) {
+            throw new RSRuntimeException("Invalid transpose passed to BLAS");
+        }
+    }
+
+    static void validateConjTranspose(@Transpose int Trans) {
+        if (Trans != NO_TRANSPOSE &&
+            Trans != CONJ_TRANSPOSE) {
+            throw new RSRuntimeException("Invalid transpose passed to BLAS");
+        }
+    }
+
+    static void validateDiag(@Diag int Diag) {
+        if (Diag != NON_UNIT && Diag != UNIT) {
+            throw new RSRuntimeException("Invalid diag passed to BLAS");
+        }
+    }
+
+    static void validateUplo(@Uplo int Uplo) {
+        if (Uplo != UPPER && Uplo != LOWER) {
+            throw new RSRuntimeException("Invalid uplo passed to BLAS");
+        }
+    }
+
+
+    /**
+     * Level 2 BLAS
+     */
+
+    static void validateGEMV(Element e, int TransA, Allocation A, Allocation X, int incX, Allocation Y, int incY) {
+        validateTranspose(TransA);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = -1, expectedYDim = -1;
+        if (TransA == NO_TRANSPOSE) {
+            expectedXDim = 1 + (N - 1) * incX;
+            expectedYDim = 1 + (M - 1) * incY;
+        } else {
+            expectedXDim = 1 + (M - 1) * incX;
+            expectedYDim = 1 + (N - 1) * incY;
+        }
+        if (X.getType().getX() != expectedXDim ||
+            Y.getType().getX() != expectedYDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for GEMV");
+        }
+    }
+
+    /**
+     * SGEMV performs one of the matrix-vector operations
+     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/d58/sgemv_8f.html
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void SGEMV(@Transpose int TransA, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+        validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DGEMV performs one of the matrix-vector operations
+     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dc/da8/dgemv_8f.html
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void DGEMV(@Transpose int TransA, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+        validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CGEMV performs one of the matrix-vector operations
+     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y   or   y := alpha*A**H*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d4/d8a/cgemv_8f.html
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void CGEMV(@Transpose int TransA, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+        validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZGEMV performs one of the matrix-vector operations
+     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y   or   y := alpha*A**H*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/d40/zgemv_8f.html
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void ZGEMV(@Transpose int TransA, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+        validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SGBMV performs one of the matrix-vector operations
+     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d6/d46/sgbmv_8f.html
+     *
+     * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+     *       but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, m):
+     *              for j in range(max(0, i-kl), min(i+ku+1, n)):
+     *                  b[i, j-i+kl] = a[i, j]
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param KL The number of sub-diagonals of the matrix A.
+     * @param KU The number of super-diagonals of the matrix A.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void SGBMV(@Transpose int TransA, int KL, int KU, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+        // GBMV has the same validation requirements as GEMV + KL and KU >= 0
+        validateGEMV(Element.F32(mRS), TransA, A, X, incX, Y, incY);
+        if (KL < 0 || KU < 0) {
+            throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
+        }
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, KL, KU, mUseIncSupp);
+    }
+
+    /**
+     * DGBMV performs one of the matrix-vector operations
+     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d2/d3f/dgbmv_8f.html
+     *
+     * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+     *       but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, m):
+     *              for j in range(max(0, i-kl), min(i+ku+1, n)):
+     *                  b[i, j-i+kl] = a[i, j]
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param KL The number of sub-diagonals of the matrix A.
+     * @param KU The number of super-diagonals of the matrix A.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void DGBMV(@Transpose int TransA, int KL, int KU, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+        // GBMV has the same validation requirements as GEMV + KL and KU >= 0
+        validateGEMV(Element.F64(mRS), TransA, A, X, incX, Y, incY);
+        if (KL < 0 || KU < 0) {
+            throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
+        }
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, aID, xID, beta, yID, incX, incY, KL, KU, mUseIncSupp);
+    }
+
+    /**
+     * CGBMV performs one of the matrix-vector operations
+     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y   or   y := alpha*A**H*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d0/d75/cgbmv_8f.html
+     *
+     * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+     *       but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, m):
+     *              for j in range(max(0, i-kl), min(i+ku+1, n)):
+     *                  b[i, j-i+kl] = a[i, j]
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param KL The number of sub-diagonals of the matrix A.
+     * @param KU The number of super-diagonals of the matrix A.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void CGBMV(@Transpose int TransA, int KL, int KU, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+        // GBMV has the same validation requirements as GEMV + KL and KU >= 0
+        validateGEMV(Element.F32_2(mRS), TransA, A, X, incX, Y, incY);
+        if (KL < 0 || KU < 0) {
+            throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
+        }
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, KL, KU, mUseIncSupp);
+    }
+
+    /**
+     * ZGBMV performs one of the matrix-vector operations
+     * y := alpha*A*x + beta*y   or   y := alpha*A**T*x + beta*y   or   y := alpha*A**H*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d9/d46/zgbmv_8f.html
+     *
+     * Note: For a M*N matrix, the input Allocation should also be of size M*N (dimY = M, dimX = N),
+     *       but only the region M*(KL+KU+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert the original matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, m):
+     *              for j in range(max(0, i-kl), min(i+ku+1, n)):
+     *                  b[i, j-i+kl] = a[i, j]
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param KL The number of sub-diagonals of the matrix A.
+     * @param KU The number of super-diagonals of the matrix A.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains the band matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void ZGBMV(@Transpose int TransA, int KL, int KU, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+        // GBMV has the same validation requirements as GEMV + KL and KU >= 0
+        validateGEMV(Element.F64_2(mRS), TransA, A, X, incX, Y, incY);
+        if (KL < 0 || KU < 0) {
+            throw new RSRuntimeException("KL and KU must be greater than or equal to 0");
+        }
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, KL, KU, mUseIncSupp);
+    }
+
+    static void validateTRMV(Element e, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTranspose(TransA);
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        int N = A.getType().getY();
+        if (A.getType().getX() != N) {
+            throw new RSRuntimeException("A must be a square matrix for TRMV");
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (X.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        if (incX <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for TRMV");
+        }
+    }
+
+    static int validateTPMV(Element e, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation Ap, Allocation X, int incX) {
+        validateTranspose(TransA);
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        if (!Ap.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (X.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        if (Ap.getType().getY() > 1) {
+            throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
+        }
+
+        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        //is it really doing anything?
+        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+            throw new RSRuntimeException("Invalid dimension for Ap");
+        }
+        if (incX <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for TPMV");
+        }
+
+        return N;
+    }
+
+    /**
+     * STRMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/de/d45/strmv_8f.html
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void STRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DTRMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dc/d7e/dtrmv_8f.html
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void DTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CTRMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x   or   x := A**H*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/df/d78/ctrmv_8f.html
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void CTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZTRMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x   or   x := A**H*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d0/dd1/ztrmv_8f.html
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void ZTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) {
+        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * STBMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d6/d7d/stbmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param K The number of off-diagonals of the matrix A
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void STBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBMV has the same requirements as TRMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DTBMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/df/d29/dtbmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param K The number of off-diagonals of the matrix A
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void DTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBMV has the same requirements as TRMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CTBMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x   or   x := A**H*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/dcd/ctbmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param K The number of off-diagonals of the matrix A
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void CTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBMV has the same requirements as TRMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZTBMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x   or   x := A**H*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/d39/ztbmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param K The number of off-diagonals of the matrix A
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void ZTBMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBMV has the same requirements as TRMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * STPMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/db1/stpmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void STPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+        int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DTPMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dc/dcd/dtpmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void DTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+        int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CTPMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x   or   x := A**H*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d4/dbb/ctpmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void CTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+        int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZTPMV performs one of the matrix-vector operations
+     * x := A*x   or   x := A**T*x   or   x := A**H*x
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d2/d9e/ztpmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void ZTPMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+        int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * STRSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d0/d2a/strsv_8f.html
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void STRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
+        // TRSV is the same as TRMV
+        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+
+    }
+
+    /**
+     * DTRSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d6/d96/dtrsv_8f.html
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void DTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
+        // TRSV is the same as TRMV
+        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+
+    }
+
+    /**
+     * CTRSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b   or   A**H*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d4/dc8/ctrsv_8f.html
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void CTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
+        // TRSV is the same as TRMV
+        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+
+    }
+
+    /**
+     * ZTRSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b   or   A**H*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d1/d2f/ztrsv_8f.html
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void ZTRSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation A,  Allocation X,  int incX) {
+        // TRSV is the same as TRMV
+        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+
+    }
+
+    /**
+     * STBSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d0/d1f/stbsv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param K The number of off-diagonals of the matrix A
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void STBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBSV is the same as TRMV + K >= 0
+        validateTRMV(Element.F32(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+        if (K < 0) {
+            throw new RSRuntimeException("Number of diagonals must be positive");
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DTBSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d4/dcf/dtbsv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param K The number of off-diagonals of the matrix A
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void DTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBSV is the same as TRMV + K >= 0
+        validateTRMV(Element.F64(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+        if (K < 0) {
+            throw new RSRuntimeException("Number of diagonals must be positive");
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, aID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CTBSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b   or   A**H*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d9/d5f/ctbsv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param K The number of off-diagonals of the matrix A
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void CTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBSV is the same as TRMV + K >= 0
+        validateTRMV(Element.F32_2(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+        if (K < 0) {
+            throw new RSRuntimeException("Number of diagonals must be positive");
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZTBSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b   or   A**H*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d4/d5a/ztbsv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param K The number of off-diagonals of the matrix A
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void ZTBSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  int K, Allocation A,  Allocation X,  int incX) {
+        // TBSV is the same as TRMV + K >= 0
+        validateTRMV(Element.F64_2(mRS), Uplo, TransA, Diag, A, X, incX);
+        int N = A.getType().getY();
+        if (K < 0) {
+            throw new RSRuntimeException("Number of diagonals must be positive");
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, aID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * STPSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d0/d7c/stpsv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void STPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+        // TPSV is same as TPMV
+        int N = validateTPMV(Element.F32(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DTPSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d9/d84/dtpsv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void DTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+        // TPSV is same as TPMV
+        int N = validateTPMV(Element.F64(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, apID, xID, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CTPSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b   or   A**H*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d8/d56/ctpsv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void CTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+        // TPSV is same as TPMV
+        int N = validateTPMV(Element.F32_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZTPSV solves one of the systems of equations
+     * A*x = b   or   A**T*x = b   or   A**H*x = b
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/da/d57/ztpsv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the matrix is an upper or lower triangular matrix.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param Ap The input allocation contains packed matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     */
+    public void ZTPSV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag,  Allocation Ap,  Allocation X,  int incX) {
+        // TPSV is same as TPMV
+        int N = validateTPMV(Element.F64_2(mRS), Uplo, TransA, Diag, Ap, X, incX);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, apID, xID, 0, 0, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * Level 2, S and D only
+     */
+    static int validateSYMV(Element e, @Uplo int Uplo, Allocation A, Allocation X, Allocation Y, int incX, int incY) {
+        validateUplo(Uplo);
+        int N = A.getType().getY();
+        if (A.getType().getX() != N) {
+            throw new RSRuntimeException("A must be a square matrix for SYMV");
+        }
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e) ) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for SYMV");
+        }
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (Y.getType().getX() != expectedYDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for SYMV");
+        }
+        return N;
+    }
+    static int validateSPMV(Element e, @Uplo int Uplo, Allocation Ap, Allocation X, int incX, Allocation Y, int incY) {
+        validateUplo(Uplo);
+        if (!Ap.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        if (Ap.getType().getY() > 1) {
+            throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
+        }
+
+        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+            throw new RSRuntimeException("Invalid dimension for Ap");
+        }
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
+        }
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (Y.getType().getX() != expectedYDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for SPMV");
+        }
+
+        return N;
+    }
+    static void validateGER(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e) ) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        if (N < 1 || M < 1) {
+            throw new RSRuntimeException("M and N must be 1 or greater for GER");
+        }
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (M - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for GER");
+        }
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (Y.getType().getX() != expectedYDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for GER");
+        }
+
+
+    }
+    static int validateSYR(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation A) {
+        validateUplo(Uplo);
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+
+        int N = A.getType().getX();
+
+        if (X.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+        if (N != A.getType().getY()) {
+            throw new RSRuntimeException("A must be a symmetric matrix");
+        }
+        if (incX <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for SYR");
+        }
+        return N;
+    }
+    static int validateSPR(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Ap) {
+        validateUplo(Uplo);
+        if (!Ap.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (X.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        if (Ap.getType().getY() > 1) {
+            throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
+        }
+
+        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+            throw new RSRuntimeException("Invalid dimension for Ap");
+        }
+        if (incX <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for SPR");
+        }
+
+        return N;
+    }
+
+    static int validateSYR2(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        validateUplo(Uplo);
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        int N = A.getType().getX();
+
+        if (N != A.getType().getY()) {
+            throw new RSRuntimeException("A must be a symmetric matrix");
+        }
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for SYR");
+        }
+        return N;
+
+    }
+    static int validateSPR2(Element e, @Uplo int Uplo, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+        validateUplo(Uplo);
+        if (!Ap.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        if (Ap.getType().getY() > 1) {
+            throw new RSRuntimeException("Ap must have a Y dimension of 0 or 1");
+        }
+
+        int N = (int)Math.sqrt((double)Ap.getType().getX() * 2);
+        if (Ap.getType().getX() != ((N * (N+1)) / 2)) {
+            throw new RSRuntimeException("Invalid dimension for Ap");
+        }
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (N - 1) * incX;
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (X.getType().getX() != expectedXDim || Y.getType().getX() != expectedYDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for SPR2");
+        }
+
+        return N;
+    }
+
+    /**
+     * SSYMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d2/d94/ssymv_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void SSYMV(@Uplo int Uplo, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+        int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SSBMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/da1/ssbmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+     * @param K The number of off-diagonals of the matrix A
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void SSBMV(@Uplo int Uplo, int K, float alpha, Allocation A, Allocation X, int incX, float beta, Allocation Y, int incY) {
+        // SBMV is the same as SYMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SSPMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d8/d68/sspmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+     * @param alpha The scalar alpha.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void SSPMV(@Uplo int Uplo, float alpha, Allocation Ap, Allocation X, int incX, float beta, Allocation Y, int incY) {
+        int N = validateSPMV(Element.F32(mRS), Uplo, Ap, X, incX, Y, incY);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, apID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SGER performs the rank 1 operation
+     * A := alpha*x*y**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/d5c/sger_8f.html
+     *
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     */
+    public void SGER(float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+        validateGER(Element.F32(mRS), X, incX, Y, incY, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sger, 0, 0, 0, 0, 0, M, N, 0, alpha, xID, yID, 0.f, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SSYR performs the rank 1 operation
+     * A := alpha*x*x**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d6/dac/ssyr_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     */
+    public void SSYR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
+        int N = validateSYR(Element.F32(mRS), Uplo, X, incX, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, aID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SSPR performs the rank 1 operation
+     * A := alpha*x*x**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d2/d9b/sspr_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     */
+    public void SSPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
+        int N = validateSPR(Element.F32(mRS), Uplo, X, incX, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, apID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SSYR2 performs the symmetric rank 2 operation
+     * A := alpha*x*y**T + alpha*y*x**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/d99/ssyr2_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     */
+    public void SSYR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        int N = validateSYR2(Element.F32(mRS), Uplo, X, incX, Y, incY, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SSPR2 performs the symmetric rank 2 operation
+     * A := alpha*x*y**T + alpha*y*x**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/d3e/sspr2_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     */
+    public void SSPR2(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+        int N = validateSPR2(Element.F32(mRS), Uplo, X, incX, Y, incY, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, apID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSYMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d8/dbe/dsymv_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void DSYMV(@Uplo int Uplo, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+        int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSBMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d8/d1e/dsbmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+     * @param K The number of off-diagonals of the matrix A
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void DSBMV(@Uplo int Uplo, int K, double alpha, Allocation A, Allocation X, int incX, double beta, Allocation Y, int incY) {
+        // SBMV is the same as SYMV + K >= 0
+        if (K < 0) {
+            throw new RSRuntimeException("K must be greater than or equal to 0");
+        }
+        int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, aID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSPMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d4/d85/dspmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+     * @param alpha The scalar alpha.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void DSPMV(@Uplo int Uplo, double alpha, Allocation Ap, Allocation X, int incX, double beta, Allocation Y, int incY) {
+        int N = validateSPMV(Element.F64(mRS), Uplo, Ap, X, incX, Y, incY);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, apID, xID, beta, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DGER performs the rank 1 operation
+     * A := alpha*x*y**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dc/da8/dger_8f.html
+     *
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     */
+    public void DGER(double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+        validateGER(Element.F64(mRS), X, incX, Y, incY, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dger, 0, 0, 0, 0, 0, M, N, 0, alpha, xID, yID, 0.f, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSYR performs the rank 1 operation
+     * A := alpha*x*x**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/d60/dsyr_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     */
+    public void DSYR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
+        int N = validateSYR(Element.F64(mRS), Uplo, X, incX, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, aID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSPR performs the rank 1 operation
+     * A := alpha*x*x**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dd/dba/dspr_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     */
+    public void DSPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
+        int N = validateSPR(Element.F64(mRS), Uplo, X, incX, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, apID, 0.f, 0, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSYR2 performs the symmetric rank 2 operation
+     * A := alpha*x*y**T + alpha*y*x**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/de/d41/dsyr2_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     */
+    public void DSYR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        int N = validateSYR2(Element.F64(mRS), Uplo, X, incX, Y, incY, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSPR2 performs the symmetric rank 2 operation
+     * A := alpha*x*y**T + alpha*y*x**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dd/d9e/dspr2_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     */
+    public void DSPR2(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+        int N = validateSPR2(Element.F64(mRS), Uplo, X, incX, Y, incY, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, xID, yID, 0, apID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+
+    /**
+     * Level 2, C and Z only
+     */
+
+    static void validateGERU(Element e, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        if (!A.getType().getElement().isCompatible(e) ||
+            !X.getType().getElement().isCompatible(e) ||
+            !Y.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (X.getType().getY() > 1 || Y.getType().getY() > 1) {
+            throw new RSRuntimeException("BLAS vectors must have Y dimension of 0 or 1");
+        }
+
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+        if (incX <= 0 || incY <= 0) {
+            throw new RSRuntimeException("Vector increments must be greater than 0");
+        }
+        int expectedXDim = 1 + (M - 1) * incX;
+        if (X.getType().getX() != expectedXDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for GERU");
+        }
+        int expectedYDim = 1 + (N - 1) * incY;
+        if (Y.getType().getX() != expectedYDim) {
+            throw new RSRuntimeException("Incorrect vector dimensions for GERU");
+        }
+
+    }
+
+    /**
+     * CHEMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d7/d51/chemv_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void CHEMV(@Uplo int Uplo, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+        // HEMV is the same as SYR2 validation-wise
+        int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CHBMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/dc2/chbmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+     * @param K The number of off-diagonals of the matrix A
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void CHBMV(@Uplo int Uplo, int K, Float2 alpha, Allocation A, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+        // HBMV is the same as SYR2 validation-wise
+        int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
+        if (K < 0) {
+            throw new RSRuntimeException("K must be 0 or greater for HBMV");
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CHPMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d2/d06/chpmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+     * @param alpha The scalar alpha.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void CHPMV(@Uplo int Uplo, Float2 alpha, Allocation Ap, Allocation X, int incX, Float2 beta, Allocation Y, int incY) {
+        // HPMV is the same as SPR2
+        int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, apID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CGERU performs the rank 1 operation
+     * A := alpha*x*y**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/d5f/cgeru_8f.html
+     *
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     */
+    public void CGERU(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CGERC performs the rank 1 operation
+     * A := alpha*x*y**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dd/d84/cgerc_8f.html
+     *
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     */
+    public void CGERC(Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        // same as GERU
+        validateGERU(Element.F32_2(mRS), X, incX, Y, incY, A);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CHER performs the rank 1 operation
+     * A := alpha*x*x**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/d6d/cher_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     */
+    public void CHER(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) {
+        // same as SYR
+        int N = validateSYR(Element.F32_2(mRS), Uplo, X, incX, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, aID, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CHPR performs the rank 1 operation
+     * A := alpha*x*x**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/dcd/chpr_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     */
+    public void CHPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) {
+        // equivalent to SPR for validation
+        int N = validateSPR(Element.F32_2(mRS), Uplo, X, incX, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, apID, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CHER2 performs the symmetric rank 2 operation
+     * A := alpha*x*y**H + alpha*y*x**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/d87/cher2_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     */
+    public void CHER2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        // same as SYR2
+        int N = validateSYR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CHPR2 performs the symmetric rank 2 operation
+     * A := alpha*x*y**H + alpha*y*x**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d6/d44/chpr2_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F32_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F32_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     */
+    public void CHPR2(@Uplo int Uplo, Float2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+        // same as SPR2
+        int N = validateSPR2(Element.F32_2(mRS), Uplo, X, incX, Y, incY, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, apID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHEMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d0/ddd/zhemv_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void ZHEMV(@Uplo int Uplo, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+        // HEMV is the same as SYR2 validation-wise
+        int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHBMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/d1a/zhbmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should also be of size N*N (dimY = N, dimX = N),
+     *       but only the region N*(K+1) will be referenced. The following subroutine can is an
+     *       example showing how to convert a UPPER trianglar matrix 'a' to row-based band matrix 'b'.
+     *           for i in range(0, n):
+     *              for j in range(i, min(i+k+1, n)):
+     *                  b[i, j-i] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of the band matrix A is being supplied.
+     * @param K The number of off-diagonals of the matrix A
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void ZHBMV(@Uplo int Uplo, int K, Double2 alpha, Allocation A, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+        // HBMV is the same as SYR2 validation-wise
+        int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
+        if (K < 0) {
+            throw new RSRuntimeException("K must be 0 or greater for HBMV");
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, aID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHPMV performs the matrix-vector operation
+     * y := alpha*A*x + beta*y
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d0/d60/zhpmv_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of the matrix A is supplied in packed form.
+     * @param alpha The scalar alpha.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param beta The scalar beta.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     */
+    public void ZHPMV(@Uplo int Uplo, Double2 alpha, Allocation Ap, Allocation X, int incX, Double2 beta, Allocation Y, int incY) {
+        // HPMV is the same as SPR2
+        int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, apID, xID, beta.x, beta.y, yID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZGERU performs the rank 1 operation
+     * A := alpha*x*y**T + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d7/d12/zgeru_8f.html
+     *
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     */
+    public void ZGERU(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZGERC performs the rank 1 operation
+     * A := alpha*x*y**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/dad/zgerc_8f.html
+     *
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     */
+    public void ZGERC(Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        // same as GERU
+        validateGERU(Element.F64_2(mRS), X, incX, Y, incY, A);
+        int M = A.getType().getY();
+        int N = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHER performs the rank 1 operation
+     * A := alpha*x*x**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/de/d0e/zher_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     */
+    public void ZHER(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) {
+        // same as SYR
+        int N = validateSYR(Element.F64_2(mRS), Uplo, X, incX, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, aID, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHPR performs the rank 1 operation
+     * A := alpha*x*x**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/de/de1/zhpr_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     */
+    public void ZHPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) {
+        // equivalent to SPR for validation
+        int N = validateSPR(Element.F64_2(mRS), Uplo, X, incX, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, xID, 0, 0, 0, apID, incX, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHER2 performs the symmetric rank 2 operation
+     * A := alpha*x*y**H + alpha*y*x**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/da/d8a/zher2_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     */
+    public void ZHER2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) {
+        // same as SYR2
+        int N = validateSYR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, A);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, aID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHPR2 performs the symmetric rank 2 operation
+     * A := alpha*x*y**H + alpha*y*x**H + A
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d5/d52/zhpr2_8f.html
+     *
+     * Note: For a N*N matrix, the input Allocation should be a 1D allocation of size dimX = N*(N+1)/2,
+     *       The following subroutine can is an example showing how to convert a UPPER trianglar matrix
+     *       'a' to packed matrix 'b'.
+     *           k = 0
+     *           for i in range(0, n):
+     *              for j in range(i, n):
+     *                  b[k++] = a[i, j]
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part is to be supplied in the packed form.
+     * @param alpha The scalar alpha.
+     * @param X The input allocation contains vector x, supported elements type {@link Element#F64_2}.
+     * @param incX The increment for the elements of vector x, must be larger than zero.
+     * @param Y The input allocation contains vector y, supported elements type {@link Element#F64_2}.
+     * @param incY The increment for the elements of vector y, must be larger than zero.
+     * @param Ap The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     */
+    public void ZHPR2(@Uplo int Uplo, Double2 alpha, Allocation X, int incX, Allocation Y, int incY, Allocation Ap) {
+        // same as SPR2
+        int N = validateSPR2(Element.F64_2(mRS), Uplo, X, incX, Y, incY, Ap);
+
+        boolean mUseIncSupp = isIncSupp();
+        long apID = Ap.getID(mRS);
+        long xID = X.getID(mRS);
+        long yID = Y.getID(mRS);
+        if (mUseIncSupp) {
+            apID = getDummyAlloc(Ap);
+            xID = getDummyAlloc(X);
+            yID = getDummyAlloc(Y);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, xID, yID, 0, 0, apID, incX, incY, 0, 0, mUseIncSupp);
+    }
+
+
+    /**
+     * Level 3 BLAS
+     */
+
+    static void validateL3(Element e, int TransA, int TransB, int Side, Allocation A, Allocation B, Allocation C) {
+        int aM = -1, aN = -1, bM = -1, bN = -1, cM = -1, cN = -1;
+        if ((A != null && !A.getType().getElement().isCompatible(e)) ||
+            (B != null && !B.getType().getElement().isCompatible(e)) ||
+            (C != null && !C.getType().getElement().isCompatible(e))) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        if (C == null) {
+            //since matrix C is used to store the result, it cannot be null.
+            throw new RSRuntimeException("Allocation C cannot be null");
+        }
+        cM = C.getType().getY();
+        cN = C.getType().getX();
+
+        if (Side == RIGHT) {
+            if ((A == null && B != null) || (A != null && B == null)) {
+                throw new RSRuntimeException("Provided Matrix A without Matrix B, or vice versa");
+            }
+            if (B != null) {
+                bM = A.getType().getY();
+                bN = A.getType().getX();
+            }
+            if (A != null) {
+                aM = B.getType().getY();
+                aN = B.getType().getX();
+            }
+        } else {
+            if (A != null) {
+                if (TransA == TRANSPOSE || TransA == CONJ_TRANSPOSE) {
+                    aN = A.getType().getY();
+                    aM = A.getType().getX();
+                } else {
+                    aM = A.getType().getY();
+                    aN = A.getType().getX();
+                }
+            }
+            if (B != null) {
+                if (TransB == TRANSPOSE || TransB == CONJ_TRANSPOSE) {
+                    bN = B.getType().getY();
+                    bM = B.getType().getX();
+                } else {
+                    bM = B.getType().getY();
+                    bN = B.getType().getX();
+                }
+            }
+        }
+        if (A != null && B != null && C != null) {
+            if (aN != bM || aM != cM || bN != cN) {
+                throw new RSRuntimeException("Called BLAS with invalid dimensions");
+            }
+        } else if (A != null && C != null) {
+            // A and C only, for SYRK
+            if (cM != cN) {
+                throw new RSRuntimeException("Matrix C is not symmetric");
+            }
+            if (aM != cM) {
+                throw new RSRuntimeException("Called BLAS with invalid dimensions");
+            }
+        } else if (A != null && B != null) {
+            // A and B only
+            if (aN != bM) {
+                throw new RSRuntimeException("Called BLAS with invalid dimensions");
+            }
+        }
+
+    }
+
+    /**
+     * SGEMM performs one of the matrix-matrix operations
+     * C := alpha*op(A)*op(B) + beta*C   where op(X) is one of op(X) = X  or  op(X) = X**T
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d4/de2/sgemm_8f.html
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param TransB The type of transpose applied to matrix B.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+     */
+    public void SGEMM(@Transpose int TransA, @Transpose int TransB, float alpha, Allocation A,
+                      Allocation B, float beta, Allocation C) {
+        validateTranspose(TransA);
+        validateTranspose(TransB);
+        validateL3(Element.F32(mRS), TransA, TransB, 0, A, B, C);
+
+        int M = -1, N = -1, K = -1;
+        if (TransA != NO_TRANSPOSE) {
+            M = A.getType().getX();
+            K = A.getType().getY();
+        } else {
+            M = A.getType().getY();
+            K = A.getType().getX();
+        }
+        if (TransB != NO_TRANSPOSE) {
+            N = B.getType().getY();
+        } else {
+            N = B.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemm, TransA, TransB, 0, 0, 0, M, N, K,  alpha, aID, bID,
+                                        beta, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DGEMM performs one of the matrix-matrix operations
+     * C := alpha*op(A)*op(B) + beta*C   where op(X) is one of op(X) = X  or  op(X) = X**T
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d7/d2b/dgemm_8f.html
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param TransB The type of transpose applied to matrix B.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+     */
+    public void DGEMM(@Transpose int TransA, @Transpose int TransB, double alpha, Allocation A,
+                      Allocation B, double beta, Allocation C) {
+        validateTranspose(TransA);
+        validateTranspose(TransB);
+        validateL3(Element.F64(mRS), TransA, TransB, 0, A, B, C);
+        int M = -1, N = -1, K = -1;
+        if (TransA != NO_TRANSPOSE) {
+            M = A.getType().getX();
+            K = A.getType().getY();
+        } else {
+            M = A.getType().getY();
+            K = A.getType().getX();
+        }
+        if (TransB != NO_TRANSPOSE) {
+            N = B.getType().getY();
+        } else {
+            N = B.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemm, TransA, TransB, 0, 0, 0, M, N, K,  alpha, aID, bID,
+                                        beta, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CGEMM performs one of the matrix-matrix operations
+     * C := alpha*op(A)*op(B) + beta*C   where op(X) is one of op(X) = X  or  op(X) = X**T  or  op(X) = X**H
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d6/d5b/cgemm_8f.html
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param TransB The type of transpose applied to matrix B.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+     */
+    public void CGEMM(@Transpose int TransA, @Transpose int TransB, Float2 alpha, Allocation A,
+                      Allocation B, Float2 beta, Allocation C) {
+        validateTranspose(TransA);
+        validateTranspose(TransB);
+        validateL3(Element.F32_2(mRS), TransA, TransB, 0, A, B, C);
+        int M = -1, N = -1, K = -1;
+        if (TransA != NO_TRANSPOSE) {
+            M = A.getType().getX();
+            K = A.getType().getY();
+        } else {
+            M = A.getType().getY();
+            K = A.getType().getX();
+        }
+        if (TransB != NO_TRANSPOSE) {
+            N = B.getType().getY();
+        } else {
+            N = B.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemm, TransA, TransB, 0, 0, 0, M, N, K,  alpha.x, alpha.y, aID, bID,
+                                         beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZGEMM performs one of the matrix-matrix operations
+     * C := alpha*op(A)*op(B) + beta*C   where op(X) is one of op(X) = X  or  op(X) = X**T  or  op(X) = X**H
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d7/d76/zgemm_8f.html
+     *
+     * @param TransA The type of transpose applied to matrix A.
+     * @param TransB The type of transpose applied to matrix B.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2
+     */
+    public void ZGEMM(@Transpose int TransA, @Transpose int TransB, Double2 alpha, Allocation A,
+                      Allocation B, Double2 beta, Allocation C) {
+        validateTranspose(TransA);
+        validateTranspose(TransB);
+        validateL3(Element.F64_2(mRS), TransA, TransB, 0, A, B, C);
+        int M = -1, N = -1, K = -1;
+        if (TransA != NO_TRANSPOSE) {
+            M = A.getType().getX();
+            K = A.getType().getY();
+        } else {
+            M = A.getType().getY();
+            K = A.getType().getX();
+        }
+        if (TransB != NO_TRANSPOSE) {
+            N = B.getType().getY();
+        } else {
+            N = B.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemm, TransA, TransB, 0, 0, 0, M, N, K,  alpha.x, alpha.y, aID, bID,
+                                   beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SSYMM performs one of the matrix-matrix operations
+     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d7/d42/ssymm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+     */
+    public void SSYMM(@Side int Side, @Uplo int Uplo, float alpha, Allocation A,
+                      Allocation B, float beta, Allocation C) {
+        validateSide(Side);
+        validateUplo(Uplo);
+        //For SYMM, Matrix A should be symmetric
+        if (A.getType().getX() != A.getType().getY()) {
+            throw new RSRuntimeException("Matrix A is not symmetric");
+        }
+        validateL3(Element.F32(mRS), 0, 0, Side, A, B, C);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, aID, bID,
+                                        beta, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSYMM performs one of the matrix-matrix operations
+     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d8/db0/dsymm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+     */
+    public void DSYMM(@Side int Side, @Uplo int Uplo, double alpha, Allocation A,
+                      Allocation B, double beta, Allocation C) {
+        validateSide(Side);
+        validateUplo(Uplo);
+        if (A.getType().getX() != A.getType().getY()) {
+            throw new RSRuntimeException("Matrix A is not symmetric");
+        }
+        validateL3(Element.F64(mRS), 0, 0, Side, A, B, C);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, aID, bID,
+                                        beta, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CSYMM performs one of the matrix-matrix operations
+     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/db/d59/csymm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+     */
+    public void CSYMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A,
+                      Allocation B, Float2 beta, Allocation C) {
+        validateSide(Side);
+        validateUplo(Uplo);
+        if (A.getType().getX() != A.getType().getY()) {
+            throw new RSRuntimeException("Matrix A is not symmetric");
+        }
+        validateL3(Element.F32_2(mRS), 0, 0, Side, A, B, C);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, aID, bID,
+                                         beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZSYMM performs one of the matrix-matrix operations
+     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/df/d51/zsymm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+     */
+    public void ZSYMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A,
+                      Allocation B, Double2 beta, Allocation C) {
+        validateSide(Side);
+        validateUplo(Uplo);
+        if (A.getType().getX() != A.getType().getY()) {
+            throw new RSRuntimeException("Matrix A is not symmetric");
+        }
+        validateL3(Element.F64_2(mRS), 0, 0, Side, A, B, C);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, aID, bID,
+                                   beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * SSYRK performs one of the symmetric rank k operations
+     * C := alpha*A*A**T + beta*C   or   C := alpha*A**T*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d0/d40/ssyrk_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+     */
+    public void SSYRK(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, float beta, Allocation C) {
+        validateTranspose(Trans);
+        validateUplo(Uplo);
+        validateL3(Element.F32(mRS), Trans, 0, 0, A, null, C);
+        int K = -1;
+        if (Trans != NO_TRANSPOSE) {
+            K = A.getType().getY();
+        } else {
+            K = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, 0, beta, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSYRK performs one of the symmetric rank k operations
+     * C := alpha*A*A**T + beta*C   or   C := alpha*A**T*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dc/d05/dsyrk_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+     */
+    public void DSYRK(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, double beta, Allocation C) {
+        validateTranspose(Trans);
+        validateUplo(Uplo);
+        validateL3(Element.F64(mRS), Trans, 0, 0, A, null, C);
+        int K = -1;
+        if (Trans != NO_TRANSPOSE) {
+            K = A.getType().getY();
+        } else {
+            K = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, 0, beta, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CSYRK performs one of the symmetric rank k operations
+     * C := alpha*A*A**T + beta*C   or   C := alpha*A**T*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/d6a/csyrk_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+     */
+    public void CSYRK(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Float2 beta, Allocation C) {
+        validateTranspose(Trans);
+        validateUplo(Uplo);
+        validateL3(Element.F32_2(mRS), Trans, 0, 0, A, null, C);
+        int K = -1;
+        if (Trans != NO_TRANSPOSE) {
+            K = A.getType().getY();
+        } else {
+            K = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, 0, beta.x, beta.y,
+                                         C.getID(mRS), 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZSYRK performs one of the symmetric rank k operations
+     * C := alpha*A*A**T + beta*C   or   C := alpha*A**T*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/de/d54/zsyrk_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+     */
+    public void ZSYRK(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Double2 beta, Allocation C) {
+        validateTranspose(Trans);
+        validateUplo(Uplo);
+        validateL3(Element.F64_2(mRS), Trans, 0, 0, A, null, C);
+        int K = -1;
+        if (Trans != NO_TRANSPOSE) {
+            K = A.getType().getY();
+        } else {
+            K = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, 0, beta.x, beta.y,
+                                   C.getID(mRS), 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    static void validateSYR2K(Element e, @Transpose int Trans, Allocation A, Allocation B, Allocation C) {
+        validateTranspose(Trans);
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e) ||
+            !C.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        int Cdim = -1;
+        // A is n x k if no transpose, k x n if transpose
+        // C is n x n
+        if (Trans == TRANSPOSE) {
+            // check columns versus C
+            Cdim = A.getType().getX();
+        } else {
+            // check rows versus C
+            Cdim = A.getType().getY();
+        }
+        if (C.getType().getX() != Cdim || C.getType().getY() != Cdim) {
+            throw new RSRuntimeException("Invalid symmetric matrix in SYR2K");
+        }
+        // A dims == B dims
+        if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
+            throw new RSRuntimeException("Invalid A and B in SYR2K");
+        }
+    }
+
+    /**
+     * SSYR2K performs one of the symmetric rank 2k operations
+     * C := alpha*A*B**T + alpha*B*A**T + beta*C   or   C := alpha*A**T*B + alpha*B**T*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/df/d3d/ssyr2k_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32}.
+     */
+    public void SSYR2K(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, Allocation B, float beta, Allocation C) {
+        validateUplo(Uplo);
+        validateSYR2K(Element.F32(mRS), Trans, A, B, C);
+        int K = -1;
+        if (Trans != NO_TRANSPOSE) {
+            K = A.getType().getY();
+        } else {
+            K = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, bID, beta, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DSYR2K performs one of the symmetric rank 2k operations
+     * C := alpha*A*B**T + alpha*B*A**T + beta*C   or   C := alpha*A**T*B + alpha*B**T*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d1/dec/dsyr2k_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64}.
+     */
+    public void DSYR2K(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, Allocation B, double beta, Allocation C) {
+        validateUplo(Uplo);
+        validateSYR2K(Element.F64(mRS), Trans, A, B, C);
+        int K = -1;
+        if (Trans != NO_TRANSPOSE) {
+            K = A.getType().getY();
+        } else {
+            K = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, aID, bID, beta, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CSYR2K performs one of the symmetric rank 2k operations
+     * C := alpha*A*B**T + alpha*B*A**T + beta*C   or   C := alpha*A**T*B + alpha*B**T*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/de/d7e/csyr2k_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+     */
+    public void CSYR2K(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
+        validateUplo(Uplo);
+        validateSYR2K(Element.F32_2(mRS), Trans, A, B, C);
+        int K = -1;
+        if (Trans != NO_TRANSPOSE) {
+            K = A.getType().getY();
+        } else {
+            K = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZSYR2K performs one of the symmetric rank 2k operations
+     * C := alpha*A*B**T + alpha*B*A**T + beta*C   or   C := alpha*A**T*B + alpha*B**T*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/df/d20/zsyr2k_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+     */
+    public void ZSYR2K(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
+        validateUplo(Uplo);
+        validateSYR2K(Element.F64_2(mRS), Trans, A, B, C);
+        int K = -1;
+        if (Trans != NO_TRANSPOSE) {
+            K = A.getType().getY();
+        } else {
+            K = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    static void validateTRMM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) {
+        validateSide(Side);
+        validateTranspose(TransA);
+        int aM = -1, aN = -1, bM = -1, bN = -1;
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+
+        aM = A.getType().getY();
+        aN = A.getType().getX();
+        if (aM != aN) {
+            throw new RSRuntimeException("Called TRMM with a non-symmetric matrix A");
+        }
+
+        bM = B.getType().getY();
+        bN = B.getType().getX();
+        if (Side == LEFT) {
+            if (aN != bM) {
+                throw new RSRuntimeException("Called TRMM with invalid matrices");
+            }
+        } else {
+            if (bN != aM) {
+                throw new RSRuntimeException("Called TRMM with invalid matrices");
+            }
+        }
+    }
+
+    /**
+     * STRMM performs one of the matrix-matrix operations
+     * B := alpha*op(A)*B   or   B := alpha*B*op(A)
+     * op(A) is one of  op(A) = A  or  op(A) = A**T
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/df/d01/strmm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether matrix A is upper or lower triangular.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+     */
+    public void STRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, float alpha, Allocation A, Allocation B) {
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        validateTRMM(Element.F32(mRS), Side, TransA, A, B);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+                                        alpha, aID, bID, 0.f, 0, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DTRMM performs one of the matrix-matrix operations
+     * B := alpha*op(A)*B   or   B := alpha*B*op(A)
+     * op(A) is one of  op(A) = A  or  op(A) = A**T
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/dd/d19/dtrmm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether matrix A is upper or lower triangular.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+     */
+    public void DTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, double alpha, Allocation A, Allocation B) {
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        validateTRMM(Element.F64(mRS), Side, TransA, A, B);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+                                        alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CTRMM performs one of the matrix-matrix operations
+     * B := alpha*op(A)*B   or   B := alpha*B*op(A)
+     * op(A) is one of  op(A) = A  or  op(A) = A**T  or  op(A) = A**H
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d4/d9b/ctrmm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether matrix A is upper or lower triangular.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+     */
+    public void CTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Float2 alpha, Allocation A, Allocation B) {
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        validateTRMM(Element.F32_2(mRS), Side, TransA, A, B);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+                                         alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZTRMM performs one of the matrix-matrix operations
+     * B := alpha*op(A)*B   or   B := alpha*B*op(A)
+     * op(A) is one of  op(A) = A  or  op(A) = A**T  or  op(A) = A**H
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d8/de1/ztrmm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether matrix A is upper or lower triangular.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+     */
+    public void ZTRMM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Double2 alpha, Allocation A, Allocation B) {
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        validateTRMM(Element.F64_2(mRS), Side, TransA, A, B);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+                                   alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    static void validateTRSM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) {
+        int adim = -1, bM = -1, bN = -1;
+        validateSide(Side);
+        validateTranspose(TransA);
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        adim = A.getType().getX();
+        if (adim != A.getType().getY()) {
+            // this may be unnecessary, the restriction could potentially be relaxed
+            // A needs to contain at least that symmetric matrix but could theoretically be larger
+            // for now we assume adapters are sufficient, will reevaluate in the future
+            throw new RSRuntimeException("Called TRSM with a non-symmetric matrix A");
+        }
+        bM = B.getType().getY();
+        bN = B.getType().getX();
+        if (Side == LEFT) {
+            // A is M*M
+            if (adim != bM) {
+                throw new RSRuntimeException("Called TRSM with invalid matrix dimensions");
+            }
+        } else {
+            // A is N*N
+            if (adim != bN) {
+                throw new RSRuntimeException("Called TRSM with invalid matrix dimensions");
+            }
+        }
+    }
+
+    /**
+     * STRSM solves one of the matrix equations
+     * op(A)*X := alpha*B   or   X*op(A) := alpha*B
+     * op(A) is one of  op(A) = A  or  op(A) = A**T
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d2/d8b/strsm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether matrix A is upper or lower triangular.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32}.
+     */
+    public void STRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, float alpha, Allocation A, Allocation B) {
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        validateTRSM(Element.F32(mRS), Side, TransA, A, B);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+        }
+        mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+                                        alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * DTRSM solves one of the matrix equations
+     * op(A)*X := alpha*B   or   X*op(A) := alpha*B
+     * op(A) is one of  op(A) = A  or  op(A) = A**T
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/de/da7/dtrsm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether matrix A is upper or lower triangular.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64}.
+     */
+    public void DTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, double alpha, Allocation A, Allocation B) {
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        validateTRSM(Element.F64(mRS), Side, TransA, A, B);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+        }
+        mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+                                        alpha, aID, bID, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * CTRSM solves one of the matrix equations
+     * op(A)*X := alpha*B   or   X*op(A) := alpha*B
+     * op(A) is one of  op(A) = A  or  op(A) = A**T  or  op(A) = A**H
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/de/d30/ctrsm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether matrix A is upper or lower triangular.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+     */
+    public void CTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Float2 alpha, Allocation A, Allocation B) {
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        validateTRSM(Element.F32_2(mRS), Side, TransA, A, B);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+                                         alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZTRSM solves one of the matrix equations
+     * op(A)*X := alpha*B   or   X*op(A) := alpha*B
+     * op(A) is one of  op(A) = A  or  op(A) = A**T  or  op(A) = A**H
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d1/d39/ztrsm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether matrix A is upper or lower triangular.
+     * @param TransA The type of transpose applied to matrix A.
+     * @param Diag Specifies whether or not A is unit triangular.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+     */
+    public void ZTRSM(@Side int Side, @Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Double2 alpha, Allocation A, Allocation B) {
+        validateUplo(Uplo);
+        validateDiag(Diag);
+        validateTRSM(Element.F64_2(mRS), Side, TransA, A, B);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0,
+                                   alpha.x, alpha.y, aID, bID, 0, 0, 0, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    static void validateHEMM(Element e, @Side int Side, Allocation A, Allocation B, Allocation C) {
+        validateSide(Side);
+
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e) ||
+            !C.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+
+        // A must be square; can potentially be relaxed similar to TRSM
+        int adim = A.getType().getX();
+        if (adim != A.getType().getY()) {
+            throw new RSRuntimeException("Called HEMM with non-square A");
+        }
+        if ((Side == LEFT && adim != B.getType().getY()) ||
+            (Side == RIGHT && adim != B.getType().getX())) {
+            throw new RSRuntimeException("Called HEMM with invalid B");
+        }
+        if (B.getType().getX() != C.getType().getX() ||
+            B.getType().getY() != C.getType().getY()) {
+            throw new RSRuntimeException("Called HEMM with mismatched B and C");
+        }
+    }
+
+    /**
+     * CHEMM performs one of the matrix-matrix operations
+     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d3/d66/chemm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+     */
+    public void CHEMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A, Allocation B, Float2 beta, Allocation C) {
+        validateUplo(Uplo);
+        validateHEMM(Element.F32_2(mRS), Side, A, B, C);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
+                                         alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHEMM performs one of the matrix-matrix operations
+     * C := alpha*A*B + beta*C   or   C := alpha*B*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d6/d3e/zhemm_8f.html
+     *
+     * @param Side Specifies whether the symmetric matrix A appears on the left or right.
+     * @param Uplo Specifies whether the upper or lower triangular part is to be referenced.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+     */
+    public void ZHEMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A, Allocation B, Double2 beta, Allocation C) {
+        validateUplo(Uplo);
+        validateHEMM(Element.F64_2(mRS), Side, A, B, C);
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0,
+                                   alpha.x, alpha.y, aID, bID, beta.x, beta.y, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    static void validateHERK(Element e, @Transpose int Trans, Allocation A, Allocation C) {
+        if (!A.getType().getElement().isCompatible(e) ||
+            !C.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        validateConjTranspose(Trans);
+        int cdim = C.getType().getX();
+        if (cdim != C.getType().getY()) {
+            throw new RSRuntimeException("Called HERK with non-square C");
+        }
+        if (Trans == NO_TRANSPOSE) {
+            if (cdim != A.getType().getY()) {
+                throw new RSRuntimeException("Called HERK with invalid A");
+            }
+        } else {
+            if (cdim != A.getType().getX()) {
+                throw new RSRuntimeException("Called HERK with invalid A");
+            }
+        }
+    }
+
+    /**
+     * CHERK performs one of the hermitian rank k operations
+     * C := alpha*A*A**H + beta*C   or   C := alpha*A**H*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d8/d52/cherk_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+     */
+    public void CHERK(@Uplo int Uplo, @Transpose int Trans, float alpha, Allocation A, float beta, Allocation C) {
+        validateUplo(Uplo);
+        validateHERK(Element.F32_2(mRS), Trans, A, C);
+        int k = 0;
+        if (Trans == CONJ_TRANSPOSE) {
+            k = A.getType().getY();
+        } else {
+            k = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k,
+                                         alpha, 0, aID, 0, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHERK performs one of the hermitian rank k operations
+     * C := alpha*A*A**H + beta*C   or   C := alpha*A**H*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d1/db1/zherk_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+     */
+    public void ZHERK(@Uplo int Uplo, @Transpose int Trans, double alpha, Allocation A, double beta, Allocation C) {
+        validateUplo(Uplo);
+        validateHERK(Element.F64_2(mRS), Trans, A, C);
+        int k = 0;
+        if (Trans == CONJ_TRANSPOSE) {
+            k = A.getType().getY();
+        } else {
+            k = A.getType().getX();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k,
+                                   alpha, 0, aID, 0, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    static void validateHER2K(Element e, @Transpose int Trans, Allocation A, Allocation B, Allocation C) {
+        if (!A.getType().getElement().isCompatible(e) ||
+            !B.getType().getElement().isCompatible(e) ||
+            !C.getType().getElement().isCompatible(e)) {
+            throw new RSRuntimeException("Called BLAS with wrong Element type");
+        }
+        validateConjTranspose(Trans);
+        int cdim = C.getType().getX();
+        if (cdim != C.getType().getY()) {
+            throw new RSRuntimeException("Called HER2K with non-square C");
+        }
+        if (Trans == NO_TRANSPOSE) {
+            if (A.getType().getY() != cdim) {
+                throw new RSRuntimeException("Called HER2K with invalid matrices");
+            }
+        } else {
+            if (A.getType().getX() != cdim) {
+                throw new RSRuntimeException("Called HER2K with invalid matrices");
+            }
+        }
+        if (A.getType().getX() != B.getType().getX() || A.getType().getY() != B.getType().getY()) {
+            throw new RSRuntimeException("Called HER2K with invalid A and B matrices");
+        }
+    }
+
+    /**
+     * CHER2K performs one of the hermitian rank 2k operations
+     * C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C   or   C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d1/d82/cher2k_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F32_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F32_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F32_2}.
+     */
+    public void CHER2K(@Uplo int Uplo, @Transpose int Trans, Float2 alpha, Allocation A, Allocation B, float beta, Allocation C) {
+        validateUplo(Uplo);
+        validateHER2K(Element.F32_2(mRS), Trans, A, B, C);
+        int k = 0;
+        if (Trans == NO_TRANSPOSE) {
+            k = A.getType().getX();
+        } else {
+            k = A.getType().getY();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y,
+                                         A.getID(mRS), bID, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+    /**
+     * ZHER2K performs one of the hermitian rank 2k operations
+     * C := alpha*A*B**H + conjg( alpha )*B*A**H + beta*C   or   C := alpha*A**H*B + conjg( alpha )*B**H*A + beta*C
+     *
+     * Details: http://www.netlib.org/lapack/explore-html/d7/dfa/zher2k_8f.html
+     *
+     * @param Uplo Specifies whether the upper or lower triangular part of C is to be referenced.
+     * @param Trans The type of transpose applied to the operation.
+     * @param alpha The scalar alpha.
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#F64_2}.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#F64_2}.
+     * @param beta The scalar beta.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#F64_2}.
+     */
+    public void ZHER2K(@Uplo int Uplo, @Transpose int Trans, Double2 alpha, Allocation A, Allocation B, double beta, Allocation C) {
+        validateUplo(Uplo);
+        validateHER2K(Element.F64_2(mRS), Trans, A, B, C);
+        int k = 0;
+        if (Trans == NO_TRANSPOSE) {
+            k = A.getType().getX();
+        } else {
+            k = A.getType().getY();
+        }
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y,
+                                   A.getID(mRS), bID, beta, 0, cID, 0, 0, 0, 0, mUseIncSupp);
+    }
+
+
+    /**
+     * 8-bit GEMM-like operation for neural networks: C = A * Transpose(B)
+     * Calculations are done in 1.10.21 fixed-point format for the final output,
+     * just before there's a shift down to drop the fractional parts. The output
+     * values are gated to 0 to 255 to fit in a byte, but the 10-bit format
+     * gives some headroom to avoid wrapping around on small overflows.
+     *
+     * @param A The input allocation contains matrix A, supported elements type {@link Element#U8}.
+     * @param a_offset The offset for all values in matrix A, e.g A[i,j] = A[i,j] - a_offset. Value should be from 0 to 255.
+     * @param B The input allocation contains matrix B, supported elements type {@link Element#U8}.
+     * @param b_offset The offset for all values in matrix B, e.g B[i,j] = B[i,j] - b_offset. Value should be from 0 to 255.
+     * @param C The input allocation contains matrix C, supported elements type {@link Element#U8}.
+     * @param c_offset The offset for all values in matrix C.
+     * @param c_mult The multiplier for all values in matrix C, e.g C[i,j] = (C[i,j] + c_offset) * c_mult.
+     **/
+    public void BNNM(Allocation A, int a_offset, Allocation B, int b_offset, Allocation C, int c_offset, int c_mult) {
+        validateL3(Element.U8(mRS), NO_TRANSPOSE, TRANSPOSE, 0, A, B, C);
+
+        if (a_offset < 0 || a_offset > 255) {
+            throw new RSRuntimeException("Invalid a_offset passed to BNNM");
+        }
+        if (b_offset < 0 || b_offset > 255) {
+            throw new RSRuntimeException("Invalid b_offset passed to BNNM");
+        }
+        int M = -1, N = -1, K = -1;
+        M = A.getType().getY();
+        N = B.getType().getY();
+        K = A.getType().getX();
+
+        boolean mUseIncSupp = isIncSupp();
+        long aID = A.getID(mRS);
+        long bID = B.getID(mRS);
+        long cID = C.getID(mRS);
+        if (mUseIncSupp) {
+            aID = getDummyAlloc(A);
+            bID = getDummyAlloc(B);
+            cID = getDummyAlloc(C);
+        }
+        mRS.nScriptIntrinsicBLAS_BNNM(getID(mRS), M, N, K, aID, a_offset, bID, b_offset, cID, c_offset, c_mult, mUseIncSupp);
+
+    }
+
+}
diff --git a/androidx/renderscript/ScriptIntrinsicBlend.java b/androidx/renderscript/ScriptIntrinsicBlend.java
new file mode 100644
index 0000000..c7e174d
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicBlend.java
@@ -0,0 +1,477 @@
+/*
+ * 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 androidx.renderscript;
+
+
+/**
+ * Intrinsic kernels for blending two
+ * {@link androidx.renderscript.Allocation} objects.
+ **/
+public class ScriptIntrinsicBlend extends ScriptIntrinsic {
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    ScriptIntrinsicBlend(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Supported elements types are {@link Element#U8_4}
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for inputs and outputs
+     *
+     * @return ScriptIntrinsicBlend
+     */
+    public static ScriptIntrinsicBlend create(RenderScript rs, Element e) {
+        // 7 comes from RS_SCRIPT_INTRINSIC_ID_BLEND in rsDefines.h
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(7, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsicBlend si = new ScriptIntrinsicBlend(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        return si;
+
+    }
+
+    private void blend(int id, Allocation ain, Allocation aout) {
+        if (!ain.getElement().isCompatible(Element.U8_4(mRS))) {
+            throw new RSIllegalArgumentException("Input is not of expected format.");
+        }
+        if (!aout.getElement().isCompatible(Element.U8_4(mRS))) {
+            throw new RSIllegalArgumentException("Output is not of expected format.");
+        }
+        forEach(id, ain, aout, null);
+    }
+
+    /**
+     * Sets dst = {0, 0, 0, 0}
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachClear(Allocation ain, Allocation aout) {
+        blend(0, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the Clear kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDClear() {
+        return createKernelID(0, 3, null, null);
+    }
+
+
+    /**
+     * Sets dst = src
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachSrc(Allocation ain, Allocation aout) {
+        blend(1, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the Src kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDSrc() {
+        return createKernelID(1, 3, null, null);
+    }
+
+    /**
+     * Sets dst = dst
+     *
+     * This is a NOP.
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachDst(Allocation ain, Allocation aout) {
+        // NOP
+    }
+
+    /**
+     * Get a KernelID for the Dst kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDDst() {
+        return createKernelID(2, 3, null, null);
+    }
+
+    /**
+     * Sets dst = src + dst * (1.0 - src.a)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachSrcOver(Allocation ain, Allocation aout) {
+        blend(3, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the SrcOver kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDSrcOver() {
+        return createKernelID(3, 3, null, null);
+    }
+
+    /**
+     * Sets dst = dst + src * (1.0 - dst.a)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachDstOver(Allocation ain, Allocation aout) {
+        blend(4, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the DstOver kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDDstOver() {
+        return createKernelID(4, 3, null, null);
+    }
+
+    /**
+     * Sets dst = src * dst.a
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachSrcIn(Allocation ain, Allocation aout) {
+        blend(5, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the SrcIn kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDSrcIn() {
+        return createKernelID(5, 3, null, null);
+    }
+
+    /**
+     * Sets dst = dst * src.a
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachDstIn(Allocation ain, Allocation aout) {
+        blend(6, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the DstIn kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDDstIn() {
+        return createKernelID(6, 3, null, null);
+    }
+
+    /**
+     * Sets dst = src * (1.0 - dst.a)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachSrcOut(Allocation ain, Allocation aout) {
+        blend(7, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the SrcOut kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDSrcOut() {
+        return createKernelID(7, 3, null, null);
+    }
+
+    /**
+     * Sets dst = dst * (1.0 - src.a)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachDstOut(Allocation ain, Allocation aout) {
+        blend(8, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the DstOut kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDDstOut() {
+        return createKernelID(8, 3, null, null);
+    }
+
+    /**
+     * dst.rgb = src.rgb * dst.a + (1.0 - src.a) * dst.rgb
+     * dst.a = dst.a
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachSrcAtop(Allocation ain, Allocation aout) {
+        blend(9, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the SrcAtop kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDSrcAtop() {
+        return createKernelID(9, 3, null, null);
+    }
+
+    /**
+     * dst = dst.rgb * src.a + (1.0 - dst.a) * src.rgb
+     * dst.a = src.a
+     * Note: Before API 23, the alpha channel was not correctly set.
+     *       Please use with caution when targeting older APIs.
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachDstAtop(Allocation ain, Allocation aout) {
+        blend(10, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the DstAtop kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDDstAtop() {
+        return createKernelID(10, 3, null, null);
+    }
+
+    /**
+     * Sets dst = {src.r ^ dst.r, src.g ^ dst.g, src.b ^ dst.b, src.a ^ dst.a}
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachXor(Allocation ain, Allocation aout) {
+        blend(11, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the Xor kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDXor() {
+        return createKernelID(11, 3, null, null);
+    }
+
+    ////////
+/*
+    public void forEachNormal(Allocation ain, Allocation aout) {
+        blend(12, ain, aout);
+    }
+
+    public void forEachAverage(Allocation ain, Allocation aout) {
+        blend(13, ain, aout);
+    }
+*/
+    /**
+     * Sets dst = src * dst
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachMultiply(Allocation ain, Allocation aout) {
+        blend(14, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the Multiply kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDMultiply() {
+        return createKernelID(14, 3, null, null);
+    }
+
+/*
+    public void forEachScreen(Allocation ain, Allocation aout) {
+        blend(15, ain, aout);
+    }
+
+    public void forEachDarken(Allocation ain, Allocation aout) {
+        blend(16, ain, aout);
+    }
+
+    public void forEachLighten(Allocation ain, Allocation aout) {
+        blend(17, ain, aout);
+    }
+
+    public void forEachOverlay(Allocation ain, Allocation aout) {
+        blend(18, ain, aout);
+    }
+
+    public void forEachHardlight(Allocation ain, Allocation aout) {
+        blend(19, ain, aout);
+    }
+
+    public void forEachSoftlight(Allocation ain, Allocation aout) {
+        blend(20, ain, aout);
+    }
+
+    public void forEachDifference(Allocation ain, Allocation aout) {
+        blend(21, ain, aout);
+    }
+
+    public void forEachNegation(Allocation ain, Allocation aout) {
+        blend(22, ain, aout);
+    }
+
+    public void forEachExclusion(Allocation ain, Allocation aout) {
+        blend(23, ain, aout);
+    }
+
+    public void forEachColorDodge(Allocation ain, Allocation aout) {
+        blend(24, ain, aout);
+    }
+
+    public void forEachInverseColorDodge(Allocation ain, Allocation aout) {
+        blend(25, ain, aout);
+    }
+
+    public void forEachSoftDodge(Allocation ain, Allocation aout) {
+        blend(26, ain, aout);
+    }
+
+    public void forEachColorBurn(Allocation ain, Allocation aout) {
+        blend(27, ain, aout);
+    }
+
+    public void forEachInverseColorBurn(Allocation ain, Allocation aout) {
+        blend(28, ain, aout);
+    }
+
+    public void forEachSoftBurn(Allocation ain, Allocation aout) {
+        blend(29, ain, aout);
+    }
+
+    public void forEachReflect(Allocation ain, Allocation aout) {
+        blend(30, ain, aout);
+    }
+
+    public void forEachGlow(Allocation ain, Allocation aout) {
+        blend(31, ain, aout);
+    }
+
+    public void forEachFreeze(Allocation ain, Allocation aout) {
+        blend(32, ain, aout);
+    }
+
+    public void forEachHeat(Allocation ain, Allocation aout) {
+        blend(33, ain, aout);
+    }
+*/
+    /**
+     * Sets dst = min(src + dst, 1.0)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachAdd(Allocation ain, Allocation aout) {
+        blend(34, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the Add kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDAdd() {
+        return createKernelID(34, 3, null, null);
+    }
+
+    /**
+     * Sets dst = max(dst - src, 0.0)
+     *
+     * @param ain The source buffer
+     * @param aout The destination buffer
+     */
+    public void forEachSubtract(Allocation ain, Allocation aout) {
+        blend(35, ain, aout);
+    }
+
+    /**
+     * Get a KernelID for the Subtract kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelIDSubtract() {
+        return createKernelID(35, 3, null, null);
+    }
+
+/*
+    public void forEachStamp(Allocation ain, Allocation aout) {
+        blend(36, ain, aout);
+    }
+
+    public void forEachRed(Allocation ain, Allocation aout) {
+        blend(37, ain, aout);
+    }
+
+    public void forEachGreen(Allocation ain, Allocation aout) {
+        blend(38, ain, aout);
+    }
+
+    public void forEachBlue(Allocation ain, Allocation aout) {
+        blend(39, ain, aout);
+    }
+
+    public void forEachHue(Allocation ain, Allocation aout) {
+        blend(40, ain, aout);
+    }
+
+    public void forEachSaturation(Allocation ain, Allocation aout) {
+        blend(41, ain, aout);
+    }
+
+    public void forEachColor(Allocation ain, Allocation aout) {
+        blend(42, ain, aout);
+    }
+
+    public void forEachLuminosity(Allocation ain, Allocation aout) {
+        blend(43, ain, aout);
+    }
+*/
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicBlur.java b/androidx/renderscript/ScriptIntrinsicBlur.java
new file mode 100644
index 0000000..4024416
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicBlur.java
@@ -0,0 +1,128 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+/**
+ * Intrinsic Gausian blur filter. Applies a gaussian blur of the
+ * specified radius to all elements of an allocation.
+ *
+ *
+ **/
+public class ScriptIntrinsicBlur extends ScriptIntrinsic {
+    private final float[] mValues = new float[9];
+    private Allocation mInput;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    protected ScriptIntrinsicBlur(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Create an intrinsic for applying a blur to an allocation. The
+     * default radius is 5.0.
+     *
+     * Supported elements types are {@link Element#U8},
+     * {@link Element#U8_4}.
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for inputs and outputs
+     *
+     * @return ScriptIntrinsicBlur
+     */
+    public static ScriptIntrinsicBlur create(RenderScript rs, Element e) {
+        if ((!e.isCompatible(Element.U8_4(rs))) && (!e.isCompatible(Element.U8(rs)))) {
+            throw new RSIllegalArgumentException("Unsupported element type.");
+        }
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(5, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsicBlur si = new ScriptIntrinsicBlur(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        si.setRadius(5.f);
+
+        return si;
+    }
+
+    /**
+     * Set the input of the blur.
+     * Must match the element type supplied during create.
+     *
+     * @param ain The input allocation
+     */
+    public void setInput(Allocation ain) {
+        if (ain.getType().getY() == 0) {
+            throw new RSIllegalArgumentException("Input set to a 1D Allocation");
+        }
+        mInput = ain;
+        setVar(1, ain);
+    }
+
+    /**
+     * Set the radius of the Blur.
+     *
+     * Supported range 0 < radius <= 25
+     *
+     * @param radius The radius of the blur
+     */
+    public void setRadius(float radius) {
+        if (radius <= 0 || radius > 25) {
+            throw new RSIllegalArgumentException("Radius out of range (0 < r <= 25).");
+        }
+        setVar(0, radius);
+    }
+
+    /**
+     * Apply the filter to the input and save to the specified
+     * allocation.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     */
+    public void forEach(Allocation aout) {
+        if (aout.getType().getY() == 0) {
+            throw new RSIllegalArgumentException("Output is a 1D Allocation");
+        }
+        forEach(0, (Allocation) null, aout, null);
+    }
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID() {
+        return createKernelID(0, 2, null, null);
+    }
+
+    /**
+     * Get a FieldID for the input field of this intrinsic.
+     *
+     * @return Script.FieldID The FieldID object.
+     */
+    public Script.FieldID getFieldID_Input() {
+        return createFieldID(1, null);
+    }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicColorMatrix.java b/androidx/renderscript/ScriptIntrinsicColorMatrix.java
new file mode 100644
index 0000000..a0a247d
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicColorMatrix.java
@@ -0,0 +1,262 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for applying a color matrix to allocations.
+ *
+ * This has the same effect as loading each element and
+ * converting it to a {@link Element#F32_4}, multiplying the
+ * result by the 4x4 color matrix as performed by
+ * rsMatrixMultiply() and writing it to the output after
+ * conversion back to {@link Element#U8_4}.
+ **/
+public class ScriptIntrinsicColorMatrix extends ScriptIntrinsic {
+    private final Matrix4f mMatrix = new Matrix4f();
+    private final Float4 mAdd = new Float4();
+    private Allocation mInput;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    protected ScriptIntrinsicColorMatrix(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Create an intrinsic for applying a color matrix to an
+     * allocation.
+     *
+     * Supported elements types are {@link Element#U8_4}
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for intputs and outputs
+     *
+     * @return ScriptIntrinsicColorMatrix
+     */
+    public static ScriptIntrinsicColorMatrix create(RenderScript rs, Element e) {
+        if (!e.isCompatible(Element.U8_4(rs))) {
+            throw new RSIllegalArgumentException("Unsupported element type.");
+        }
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(2, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsicColorMatrix si = new ScriptIntrinsicColorMatrix(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        return si;
+
+    }
+
+    private void setMatrix() {
+        FieldPacker fp = new FieldPacker(16*4);
+        fp.addMatrix(mMatrix);
+        setVar(0, fp);
+    }
+
+    /**
+     * Set the color matrix which will be applied to each cell of
+     * the image.
+     *
+     * @param m The 4x4 matrix to set.
+     */
+    public void setColorMatrix(Matrix4f m) {
+        mMatrix.load(m);
+        setMatrix();
+    }
+
+    /**
+     * Set the color matrix which will be applied to each cell of the image.
+     * This will set the alpha channel to be a copy.
+     *
+     * @param m The 3x3 matrix to set.
+     */
+    public void setColorMatrix(Matrix3f m) {
+        mMatrix.load(m);
+        setMatrix();
+    }
+
+    /**
+     * Set the value to be added after the color matrix has been
+     * applied. The default value is {0, 0, 0, 0}
+     *
+     * @param f The float4 value to be added.
+     */
+    public void setAdd(Float4 f) {
+        mAdd.x = f.x;
+        mAdd.y = f.y;
+        mAdd.z = f.z;
+        mAdd.w = f.w;
+
+        FieldPacker fp = new FieldPacker(4*4);
+        fp.addF32(f.x);
+        fp.addF32(f.y);
+        fp.addF32(f.z);
+        fp.addF32(f.w);
+        setVar(1, fp);
+    }
+
+    /**
+     * Set the value to be added after the color matrix has been
+     * applied. The default value is {0, 0, 0, 0}
+     *
+     * @param r The red add value.
+     * @param g The green add value.
+     * @param b The blue add value.
+     * @param a The alpha add value.
+     */
+    public void setAdd(float r, float g, float b, float a) {
+        mAdd.x = r;
+        mAdd.y = g;
+        mAdd.z = b;
+        mAdd.w = a;
+
+        FieldPacker fp = new FieldPacker(4*4);
+        fp.addF32(mAdd.x);
+        fp.addF32(mAdd.y);
+        fp.addF32(mAdd.z);
+        fp.addF32(mAdd.w);
+        setVar(1, fp);
+    }
+
+    /**
+     * Set a color matrix to convert from RGB to luminance. The alpha channel
+     * will be a copy.
+     *
+     */
+    public void setGreyscale() {
+        mMatrix.loadIdentity();
+        mMatrix.set(0, 0, 0.299f);
+        mMatrix.set(1, 0, 0.587f);
+        mMatrix.set(2, 0, 0.114f);
+        mMatrix.set(0, 1, 0.299f);
+        mMatrix.set(1, 1, 0.587f);
+        mMatrix.set(2, 1, 0.114f);
+        mMatrix.set(0, 2, 0.299f);
+        mMatrix.set(1, 2, 0.587f);
+        mMatrix.set(2, 2, 0.114f);
+        setMatrix();
+    }
+
+    /**
+     * Set the matrix to convert from YUV to RGB with a direct copy of the 4th
+     * channel.
+     *
+     */
+    public void setYUVtoRGB() {
+        mMatrix.loadIdentity();
+        mMatrix.set(0, 0, 1.f);
+        mMatrix.set(1, 0, 0.f);
+        mMatrix.set(2, 0, 1.13983f);
+        mMatrix.set(0, 1, 1.f);
+        mMatrix.set(1, 1, -0.39465f);
+        mMatrix.set(2, 1, -0.5806f);
+        mMatrix.set(0, 2, 1.f);
+        mMatrix.set(1, 2, 2.03211f);
+        mMatrix.set(2, 2, 0.f);
+        setMatrix();
+    }
+
+    /**
+     * Set the matrix to convert from RGB to YUV with a direct copy of the 4th
+     * channel.
+     *
+     */
+    public void setRGBtoYUV() {
+        mMatrix.loadIdentity();
+        mMatrix.set(0, 0, 0.299f);
+        mMatrix.set(1, 0, 0.587f);
+        mMatrix.set(2, 0, 0.114f);
+        mMatrix.set(0, 1, -0.14713f);
+        mMatrix.set(1, 1, -0.28886f);
+        mMatrix.set(2, 1, 0.436f);
+        mMatrix.set(0, 2, 0.615f);
+        mMatrix.set(1, 2, -0.51499f);
+        mMatrix.set(2, 2, -0.10001f);
+        setMatrix();
+    }
+
+
+    /**
+     * Invoke the kernel and apply the matrix to each cell of ain and copy to
+     * aout.
+     *
+     * @param ain Input allocation
+     * @param aout Output allocation
+     */
+    public void forEach(Allocation ain, Allocation aout) {
+        forEach(0, ain, aout, null);
+    }
+
+    /**
+     * Invoke the kernel and apply the matrix to each cell of input
+     * {@link Allocation} and copy to the output {@link Allocation}.
+     *
+     * If the vector size of the input is less than four, the
+     * remaining components are treated as zero for the matrix
+     * multiply.
+     *
+     * If the output vector size is less than four, the unused
+     * vector components are discarded.
+     *
+     *
+     * @param ain Input allocation
+     * @param aout Output allocation
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
+        if (!ain.getElement().isCompatible(Element.U8(mRS)) &&
+            !ain.getElement().isCompatible(Element.U8_2(mRS)) &&
+            !ain.getElement().isCompatible(Element.U8_3(mRS)) &&
+            !ain.getElement().isCompatible(Element.U8_4(mRS)) &&
+            !ain.getElement().isCompatible(Element.F32(mRS)) &&
+            !ain.getElement().isCompatible(Element.F32_2(mRS)) &&
+            !ain.getElement().isCompatible(Element.F32_3(mRS)) &&
+            !ain.getElement().isCompatible(Element.F32_4(mRS))) {
+
+            throw new RSIllegalArgumentException("Unsupported element type.");
+        }
+
+        if (!aout.getElement().isCompatible(Element.U8(mRS)) &&
+            !aout.getElement().isCompatible(Element.U8_2(mRS)) &&
+            !aout.getElement().isCompatible(Element.U8_3(mRS)) &&
+            !aout.getElement().isCompatible(Element.U8_4(mRS)) &&
+            !aout.getElement().isCompatible(Element.F32(mRS)) &&
+            !aout.getElement().isCompatible(Element.F32_2(mRS)) &&
+            !aout.getElement().isCompatible(Element.F32_3(mRS)) &&
+            !aout.getElement().isCompatible(Element.F32_4(mRS))) {
+
+            throw new RSIllegalArgumentException("Unsupported element type.");
+        }
+
+        forEach(0, ain, aout, null, opt);
+    }
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID() {
+        return createKernelID(0, 3, null, null);
+    }
+
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicConvolve3x3.java b/androidx/renderscript/ScriptIntrinsicConvolve3x3.java
new file mode 100644
index 0000000..d4e57b0
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicConvolve3x3.java
@@ -0,0 +1,151 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for applying a 3x3 convolve to an allocation.
+ *
+ **/
+public class ScriptIntrinsicConvolve3x3 extends ScriptIntrinsic {
+    private final float[] mValues = new float[9];
+    private Allocation mInput;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    ScriptIntrinsicConvolve3x3(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Supported elements types are {@link Element#U8}, {@link
+     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+     * {@link Element#F32}, {@link Element#F32_2}, {@link
+     * Element#F32_3}, and {@link Element#F32_4}.
+     *
+     * <p> The default coefficients are:
+     * <code>
+     * <p> [ 0,  0,  0 ]
+     * <p> [ 0,  1,  0 ]
+     * <p> [ 0,  0,  0 ]
+     * </code>
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for intputs and outputs
+     *
+     * @return ScriptIntrinsicConvolve3x3
+     */
+    public static ScriptIntrinsicConvolve3x3 create(RenderScript rs, Element e) {
+        float f[] = { 0, 0, 0, 0, 1, 0, 0, 0, 0};
+        if (!e.isCompatible(Element.U8(rs)) &&
+            !e.isCompatible(Element.U8_2(rs)) &&
+            !e.isCompatible(Element.U8_3(rs)) &&
+            !e.isCompatible(Element.U8_4(rs)) &&
+            !e.isCompatible(Element.F32(rs)) &&
+            !e.isCompatible(Element.F32_2(rs)) &&
+            !e.isCompatible(Element.F32_3(rs)) &&
+            !e.isCompatible(Element.F32_4(rs))) {
+            throw new RSIllegalArgumentException("Unsupported element type.");
+        }
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(1, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsicConvolve3x3 si = new ScriptIntrinsicConvolve3x3(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        si.setCoefficients(f);
+        return si;
+    }
+
+    /**
+     * Set the input of the 3x3 convolve.
+     * Must match the element type supplied during create.
+     *
+     * @param ain The input allocation.
+     */
+    public void setInput(Allocation ain) {
+        mInput = ain;
+        setVar(1, ain);
+    }
+
+    /**
+     * Set the coefficients for the convolve.
+     *
+     * <p> The convolve layout is:
+     * <code>
+     * <p> [ 0,  1,  2 ]
+     * <p> [ 3,  4,  5 ]
+     * <p> [ 6,  7,  8 ]
+     * </code>
+     *
+     * @param v The array of coefficients to set
+     */
+    public void setCoefficients(float v[]) {
+        FieldPacker fp = new FieldPacker(9*4);
+        for (int ct=0; ct < mValues.length; ct++) {
+            mValues[ct] = v[ct];
+            fp.addF32(mValues[ct]);
+        }
+        setVar(0, fp);
+    }
+
+    /**
+     * Apply the filter to the input and save to the specified
+     * allocation.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     */
+    public void forEach(Allocation aout) {
+        forEach(0, (Allocation) null, aout, null);
+    }
+
+    /**
+     * Apply the filter to the input and save to the specified
+     * allocation.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation aout, Script.LaunchOptions opt) {
+        forEach(0, (Allocation) null, aout, null, opt);
+    }
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID() {
+        return createKernelID(0, 2, null, null);
+    }
+
+    /**
+     * Get a FieldID for the input field of this intrinsic.
+     *
+     * @return Script.FieldID The FieldID object.
+     */
+    public Script.FieldID getFieldID_Input() {
+        return createFieldID(1, null);
+    }
+
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicConvolve5x5.java b/androidx/renderscript/ScriptIntrinsicConvolve5x5.java
new file mode 100644
index 0000000..298596e
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicConvolve5x5.java
@@ -0,0 +1,154 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for applying a 5x5 convolve to an allocation.
+ *
+ **/
+public class ScriptIntrinsicConvolve5x5 extends ScriptIntrinsic {
+    private final float[] mValues = new float[25];
+    private Allocation mInput;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    ScriptIntrinsicConvolve5x5(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Supported elements types are {@link Element#U8}, {@link
+     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
+     * {@link Element#F32}, {@link Element#F32_2}, {@link
+     * Element#F32_3}, and {@link Element#F32_4}.
+     *
+     * <p> The default coefficients are:
+     * <code>
+     * <p> [ 0,  0,  0,  0,  0  ]
+     * <p> [ 0,  0,  0,  0,  0  ]
+     * <p> [ 0,  0,  1,  0,  0  ]
+     * <p> [ 0,  0,  0,  0,  0  ]
+     * <p> [ 0,  0,  0,  0,  0  ]
+     * </code>
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for intputs and outputs
+     *
+     * @return ScriptIntrinsicConvolve5x5
+     */
+    public static ScriptIntrinsicConvolve5x5 create(RenderScript rs, Element e) {
+        if (!e.isCompatible(Element.U8(rs)) &&
+            !e.isCompatible(Element.U8_2(rs)) &&
+            !e.isCompatible(Element.U8_3(rs)) &&
+            !e.isCompatible(Element.U8_4(rs)) &&
+            !e.isCompatible(Element.F32(rs)) &&
+            !e.isCompatible(Element.F32_2(rs)) &&
+            !e.isCompatible(Element.F32_3(rs)) &&
+            !e.isCompatible(Element.F32_4(rs))) {
+            throw new RSIllegalArgumentException("Unsupported element type.");
+        }
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(4, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsicConvolve5x5 si = new ScriptIntrinsicConvolve5x5(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        return si;
+
+    }
+
+    /**
+     * Set the input of the 5x5 convolve.
+     * Must match the element type supplied during create.
+     *
+     * @param ain The input allocation.
+     */
+    public void setInput(Allocation ain) {
+        mInput = ain;
+        setVar(1, ain);
+    }
+
+    /**
+    * Set the coefficients for the convolve.
+    *
+    * <p> The convolve layout is:
+    * <code>
+    * <p> [ 0,  1,  2,  3,  4  ]
+    * <p> [ 5,  6,  7,  8,  9  ]
+    * <p> [ 10, 11, 12, 13, 14 ]
+    * <p> [ 15, 16, 17, 18, 19 ]
+    * <p> [ 20, 21, 22, 23, 24 ]
+    * </code>
+    *
+    * @param v The array of coefficients to set
+    */
+    public void setCoefficients(float v[]) {
+        FieldPacker fp = new FieldPacker(25*4);
+        for (int ct=0; ct < mValues.length; ct++) {
+            mValues[ct] = v[ct];
+            fp.addF32(mValues[ct]);
+        }
+        setVar(0, fp);
+    }
+
+    /**
+     * Apply the filter to the input and save to the specified
+     * allocation.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     */
+    public void forEach(Allocation aout) {
+        forEach(0, (Allocation) null, aout, null);
+    }
+
+    /**
+     * Apply the filter to the input and save to the specified
+     * allocation.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation aout, Script.LaunchOptions opt) {
+        forEach(0, (Allocation) null, aout, null, opt);
+    }
+
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID() {
+        return createKernelID(0, 2, null, null);
+    }
+
+    /**
+     * Get a FieldID for the input field of this intrinsic.
+     *
+     * @return Script.FieldID The FieldID object.
+     */
+    public Script.FieldID getFieldID_Input() {
+        return createFieldID(1, null);
+    }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicHistogram.java b/androidx/renderscript/ScriptIntrinsicHistogram.java
new file mode 100644
index 0000000..3437f2c
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicHistogram.java
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2015 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 androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic Histogram filter.
+ *
+ *
+ **/
+public class ScriptIntrinsicHistogram extends ScriptIntrinsic {
+    private Allocation mOut;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    protected ScriptIntrinsicHistogram(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Create an intrinsic for calculating the histogram of an uchar
+     * or uchar4 image.
+     *
+     * Supported elements types are
+     * {@link Element#U8_4}, {@link Element#U8_3},
+     * {@link Element#U8_2}, {@link Element#U8}
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for inputs
+     *
+     * @return ScriptIntrinsicHistogram
+     */
+    public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
+        if ((!e.isCompatible(Element.U8_4(rs))) &&
+            (!e.isCompatible(Element.U8_3(rs))) &&
+            (!e.isCompatible(Element.U8_2(rs))) &&
+            (!e.isCompatible(Element.U8(rs)))) {
+            throw new RSIllegalArgumentException("Unsupported element type.");
+        }
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(9, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsicHistogram si = new ScriptIntrinsicHistogram(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        return si;
+    }
+
+    /**
+     * Process an input buffer and place the histogram into the
+     * output allocation. The output allocation may be a narrower
+     * vector size than the input. In this case the vector size of
+     * the output is used to determine how many of the input
+     * channels are used in the computation. This is useful if you
+     * have an RGBA input buffer but only want the histogram for
+     * RGB.
+     *
+     * 1D and 2D input allocations are supported.
+     *
+     * @param ain The input image
+     */
+    public void forEach(Allocation ain) {
+        forEach(ain, null);
+    }
+
+    /**
+     * Process an input buffer and place the histogram into the
+     * output allocation. The output allocation may be a narrower
+     * vector size than the input. In this case the vector size of
+     * the output is used to determine how many of the input
+     * channels are used in the computation. This is useful if you
+     * have an RGBA input buffer but only want the histogram for
+     * RGB.
+     *
+     * 1D and 2D input allocations are supported.
+     *
+     * @param ain The input image
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach(Allocation ain, Script.LaunchOptions opt) {
+        if (ain.getType().getElement().getVectorSize() <
+            mOut.getType().getElement().getVectorSize()) {
+
+            throw new RSIllegalArgumentException(
+                "Input vector size must be >= output vector size.");
+        }
+        if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
+            !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
+            !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
+            !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
+            throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
+        }
+
+        forEach(0, ain, null, null, opt);
+    }
+
+
+
+    /**
+     * Set the coefficients used for the RGBA to Luminocity
+     * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
+     *
+     * Coefficients must be >= 0 and sum to 1.0 or less.
+     *
+     * @param r Red coefficient
+     * @param g Green coefficient
+     * @param b Blue coefficient
+     * @param a Alpha coefficient
+     */
+    public void setDotCoefficients(float r, float g, float b, float a) {
+        if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
+            throw new RSIllegalArgumentException("Coefficient may not be negative.");
+        }
+        if ((r + g + b + a) > 1.f) {
+            throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
+        }
+
+        FieldPacker fp = new FieldPacker(16);
+        fp.addF32(r);
+        fp.addF32(g);
+        fp.addF32(b);
+        fp.addF32(a);
+        setVar(0, fp);
+    }
+
+    /**
+     * Set the output of the histogram.  32 bit integer types are
+     * supported.
+     *
+     * @param aout The output allocation
+     */
+    public void setOutput(Allocation aout) {
+        mOut = aout;
+        if (mOut.getType().getElement() != Element.U32(mRS) &&
+            mOut.getType().getElement() != Element.U32_2(mRS) &&
+            mOut.getType().getElement() != Element.U32_3(mRS) &&
+            mOut.getType().getElement() != Element.U32_4(mRS) &&
+            mOut.getType().getElement() != Element.I32(mRS) &&
+            mOut.getType().getElement() != Element.I32_2(mRS) &&
+            mOut.getType().getElement() != Element.I32_3(mRS) &&
+            mOut.getType().getElement() != Element.I32_4(mRS)) {
+
+            throw new RSIllegalArgumentException("Output type must be U32 or I32.");
+        }
+        if ((mOut.getType().getX() != 256) ||
+            (mOut.getType().getY() != 0) ||
+            mOut.getType().hasMipmaps() ||
+            (mOut.getType().getYuv() != 0)) {
+
+            throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
+        }
+        setVar(1, aout);
+    }
+
+
+    /**
+     * Process an input buffer and place the histogram into the
+     * output allocation. The dot product of the input channel and
+     * the coefficients from 'setDotCoefficients' are used to
+     * calculate the output values.
+     *
+     * 1D and 2D input allocations are supported.
+     *
+     * @param ain The input image
+     */
+    public void forEach_Dot(Allocation ain) {
+        forEach_Dot(ain, null);
+    }
+
+    /**
+     * Process an input buffer and place the histogram into the
+     * output allocation. The dot product of the input channel and
+     * the coefficients from 'setDotCoefficients' are used to
+     * calculate the output values.
+     *
+     * 1D and 2D input allocations are supported.
+     *
+     * @param ain The input image
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
+        if (mOut.getType().getElement().getVectorSize() != 1) {
+            throw new RSIllegalArgumentException("Output vector size must be one.");
+        }
+        if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
+            !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
+            !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
+            !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
+            throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
+        }
+
+        forEach(1, ain, null, null, opt);
+    }
+
+
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID_Separate() {
+        return createKernelID(0, 3, null, null);
+    }
+
+    /**
+     * Get a FieldID for the input field of this intrinsic.
+     *
+     * @return Script.FieldID The FieldID object.
+     */
+    public Script.FieldID getFieldID_Input() {
+        return createFieldID(1, null);
+    }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicLUT.java b/androidx/renderscript/ScriptIntrinsicLUT.java
new file mode 100644
index 0000000..6434903
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicLUT.java
@@ -0,0 +1,152 @@
+/*
+ * 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 androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for applying a per-channel lookup table. Each
+ * channel of the input has an independant lookup table. The
+ * tables are 256 entries in size and can cover the full value
+ * range of {@link Element#U8_4}.
+ **/
+public class ScriptIntrinsicLUT extends ScriptIntrinsic {
+    private final Matrix4f mMatrix = new Matrix4f();
+    private Allocation mTables;
+    private final byte mCache[] = new byte[1024];
+    private boolean mDirty = true;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    protected ScriptIntrinsicLUT(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Supported elements types are {@link Element#U8_4}
+     *
+     * The defaults tables are identity.
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for intputs and outputs
+     *
+     * @return ScriptIntrinsicLUT
+     */
+    public static ScriptIntrinsicLUT create(RenderScript rs, Element e) {
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(3, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsicLUT si = new ScriptIntrinsicLUT(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        si.mTables = Allocation.createSized(rs, Element.U8(rs), 1024);
+        for (int ct=0; ct < 256; ct++) {
+            si.mCache[ct] = (byte)ct;
+            si.mCache[ct + 256] = (byte)ct;
+            si.mCache[ct + 512] = (byte)ct;
+            si.mCache[ct + 768] = (byte)ct;
+        }
+        si.setVar(0, si.mTables);
+        return si;
+    }
+
+
+    private void validate(int index, int value) {
+        if (index < 0 || index > 255) {
+            throw new RSIllegalArgumentException("Index out of range (0-255).");
+        }
+        if (value < 0 || value > 255) {
+            throw new RSIllegalArgumentException("Value out of range (0-255).");
+        }
+    }
+
+    /**
+     * Set an entry in the red channel lookup table
+     *
+     * @param index Must be 0-255
+     * @param value Must be 0-255
+     */
+    public void setRed(int index, int value) {
+        validate(index, value);
+        mCache[index] = (byte)value;
+        mDirty = true;
+    }
+
+    /**
+     * Set an entry in the green channel lookup table
+     *
+     * @param index Must be 0-255
+     * @param value Must be 0-255
+     */
+    public void setGreen(int index, int value) {
+        validate(index, value);
+        mCache[index+256] = (byte)value;
+        mDirty = true;
+    }
+
+    /**
+     * Set an entry in the blue channel lookup table
+     *
+     * @param index Must be 0-255
+     * @param value Must be 0-255
+     */
+    public void setBlue(int index, int value) {
+        validate(index, value);
+        mCache[index+512] = (byte)value;
+        mDirty = true;
+    }
+
+    /**
+     * Set an entry in the alpha channel lookup table
+     *
+     * @param index Must be 0-255
+     * @param value Must be 0-255
+     */
+    public void setAlpha(int index, int value) {
+        validate(index, value);
+        mCache[index+768] = (byte)value;
+        mDirty = true;
+    }
+
+
+    /**
+     * Invoke the kernel and apply the lookup to each cell of ain
+     * and copy to aout.
+     *
+     * @param ain Input allocation
+     * @param aout Output allocation
+     */
+    public void forEach(Allocation ain, Allocation aout) {
+        if (mDirty) {
+            mDirty = false;
+            mTables.copyFromUnchecked(mCache);
+        }
+        forEach(0, ain, aout, null);
+    }
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID() {
+        return createKernelID(0, 3, null, null);
+    }
+}
+
diff --git a/androidx/renderscript/ScriptIntrinsicResize.java b/androidx/renderscript/ScriptIntrinsicResize.java
new file mode 100644
index 0000000..c3450f1
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicResize.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2015 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 androidx.renderscript;
+
+import android.util.Log;
+
+/**
+ * Intrinsic for performing a resize of a 2D allocation.
+ */
+public class ScriptIntrinsicResize extends ScriptIntrinsic {
+    private Allocation mInput;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 21;
+
+    protected ScriptIntrinsicResize(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Supported elements types are {@link Element#U8}, {@link
+     * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4}
+     * {@link Element#F32}, {@link Element#F32_2}, {@link
+     * Element#F32_3}, {@link Element#F32_4}
+     *
+     * @param rs The RenderScript context
+     *
+     * @return ScriptIntrinsicResize
+     */
+    public static ScriptIntrinsicResize create(RenderScript rs) {
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(12, 0, mUseIncSupp);
+
+        ScriptIntrinsicResize si = new ScriptIntrinsicResize(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        return si;
+
+    }
+
+    /**
+     * Set the input of the resize.
+     * Must match the element type supplied during create.
+     *
+     * @param ain The input allocation.
+     */
+    public void setInput(Allocation ain) {
+        Element e = ain.getElement();
+        if (!e.isCompatible(Element.U8(mRS)) &&
+            !e.isCompatible(Element.U8_2(mRS)) &&
+            !e.isCompatible(Element.U8_3(mRS)) &&
+            !e.isCompatible(Element.U8_4(mRS)) &&
+            !e.isCompatible(Element.F32(mRS)) &&
+            !e.isCompatible(Element.F32_2(mRS)) &&
+            !e.isCompatible(Element.F32_3(mRS)) &&
+            !e.isCompatible(Element.F32_4(mRS))) {
+            throw new RSIllegalArgumentException("Unsupported element type.");
+        }
+
+        mInput = ain;
+        setVar(0, ain);
+    }
+
+    /**
+     * Get a FieldID for the input field of this intrinsic.
+     *
+     * @return Script.FieldID The FieldID object.
+     */
+    public Script.FieldID getFieldID_Input() {
+        return createFieldID(0, null);
+    }
+
+
+    /**
+     * Resize copy the input allocation to the output specified. The
+     * Allocation is rescaled if necessary using bi-cubic
+     * interpolation.
+     *
+     * @param aout Output allocation. Element type must match
+     *             current input.  Must not be same as input.
+     */
+    public void forEach_bicubic(Allocation aout) {
+        if (aout == mInput) {
+            throw new RSIllegalArgumentException("Output cannot be same as Input.");
+        }
+        forEach_bicubic(aout, null);
+    }
+
+    /**
+     * Resize copy the input allocation to the output specified. The
+     * Allocation is rescaled if necessary using bi-cubic
+     * interpolation.
+     *
+     * @param aout Output allocation. Element type must match
+     *             current input.
+     * @param opt LaunchOptions for clipping
+     */
+    public void forEach_bicubic(Allocation aout, Script.LaunchOptions opt) {
+        forEach(0, (Allocation) null, aout, null, opt);
+    }
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID_bicubic() {
+        return createKernelID(0, 2, null, null);
+    }
+
+
+}
diff --git a/androidx/renderscript/ScriptIntrinsicYuvToRGB.java b/androidx/renderscript/ScriptIntrinsicYuvToRGB.java
new file mode 100644
index 0000000..8749398
--- /dev/null
+++ b/androidx/renderscript/ScriptIntrinsicYuvToRGB.java
@@ -0,0 +1,97 @@
+/*
+ * 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 androidx.renderscript;
+
+
+/**
+ * Intrinsic for converting an Android YUV buffer to RGB.
+ *
+ * The input allocation is supplied in NV21 format as a U8
+ * element type. The output is RGBA, the alpha channel will be
+ * set to 255.
+ */
+public class ScriptIntrinsicYuvToRGB extends ScriptIntrinsic {
+    private Allocation mInput;
+    // API level for the intrinsic
+    private static final int INTRINSIC_API_LEVEL = 19;
+
+    ScriptIntrinsicYuvToRGB(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /**
+     * Create an intrinsic for converting YUV to RGB.
+     *
+     * Supported elements types are {@link Element#U8_4}
+     *
+     * @param rs The RenderScript context
+     * @param e Element type for output
+     *
+     * @return ScriptIntrinsicYuvToRGB
+     */
+    public static ScriptIntrinsicYuvToRGB create(RenderScript rs, Element e) {
+        // 6 comes from RS_SCRIPT_INTRINSIC_YUV_TO_RGB in rsDefines.h
+        long id;
+        boolean mUseIncSupp = rs.isUseNative() &&
+                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
+
+        id = rs.nScriptIntrinsicCreate(6, e.getID(rs), mUseIncSupp);
+
+        ScriptIntrinsicYuvToRGB si = new ScriptIntrinsicYuvToRGB(id, rs);
+        si.setIncSupp(mUseIncSupp);
+        return si;
+    }
+
+
+    /**
+     * Set the input yuv allocation, must be {@link Element#U8}.
+     *
+     * @param ain The input allocation.
+     */
+    public void setInput(Allocation ain) {
+        mInput = ain;
+        setVar(0, ain);
+    }
+
+    /**
+     * Convert the image to RGB.
+     *
+     * @param aout Output allocation. Must match creation element
+     *             type.
+     */
+    public void forEach(Allocation aout) {
+        forEach(0, (Allocation) null, aout, null);
+    }
+
+    /**
+     * Get a KernelID for this intrinsic kernel.
+     *
+     * @return Script.KernelID The KernelID object.
+     */
+    public Script.KernelID getKernelID() {
+        return createKernelID(0, 2, null, null);
+    }
+
+    /**
+     * Get a FieldID for the input field of this intrinsic.
+     *
+     * @return Script.FieldID The FieldID object.
+     */
+    public Script.FieldID getFieldID_Input() {
+        return createFieldID(0, null);
+    }
+}
diff --git a/androidx/renderscript/Short2.java b/androidx/renderscript/Short2.java
new file mode 100644
index 0000000..f06d746
--- /dev/null
+++ b/androidx/renderscript/Short2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript Short2 type back to the Android system.
+ *
+ **/
+public class Short2 {
+    public Short2() {
+    }
+
+    public Short2(short initX, short initY) {
+        x = initX;
+        y = initY;
+    }
+
+    public short x;
+    public short y;
+}
+
+
+
+
diff --git a/androidx/renderscript/Short3.java b/androidx/renderscript/Short3.java
new file mode 100644
index 0000000..fbf9a89
--- /dev/null
+++ b/androidx/renderscript/Short3.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript short3 type back to the Android system.
+ *
+ **/
+public class Short3 {
+    public Short3() {
+    }
+
+    public Short3(short initX, short initY, short initZ) {
+        x = initX;
+        y = initY;
+        z = initZ;
+    }
+
+    public short x;
+    public short y;
+    public short z;
+}
+
+
+
+
diff --git a/androidx/renderscript/Short4.java b/androidx/renderscript/Short4.java
new file mode 100644
index 0000000..1e479d2
--- /dev/null
+++ b/androidx/renderscript/Short4.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2009 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 androidx.renderscript;
+
+import java.lang.Math;
+import android.util.Log;
+
+
+/**
+ * Class for exposing the native RenderScript short4 type back to the Android system.
+ *
+ **/
+public class Short4 {
+    public Short4() {
+    }
+
+    public Short4(short initX, short initY, short initZ, short initW) {
+        x = initX;
+        y = initY;
+        z = initZ;
+        w = initW;
+    }
+
+    public short x;
+    public short y;
+    public short z;
+    public short w;
+}
+
+
+
diff --git a/androidx/renderscript/Type.java b/androidx/renderscript/Type.java
new file mode 100644
index 0000000..cec834c
--- /dev/null
+++ b/androidx/renderscript/Type.java
@@ -0,0 +1,411 @@
+/*
+ * Copyright (C) 2013 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 androidx.renderscript;
+
+
+import java.lang.reflect.Field;
+
+import android.graphics.ImageFormat;
+import android.util.Log;
+
+/**
+ * <p>A Type describes the {@link androidx.renderscript.Element} and
+ * dimensions used for an {@link androidx.renderscript.Allocation} or
+ * a parallel operation. Types are created through
+ * {@link androidx.renderscript.Type.Builder}.</p>
+ *
+ * <p>A Type always includes an {@link androidx.renderscript.Element}
+ * and an X dimension. A Type may be multidimensional, up to three dimensions.
+ * A nonzero value in the Y or Z dimensions indicates that the dimension is
+ * present. Note that a Type with only a given X dimension and a Type with the
+ * same X dimension but Y = 1 are not equivalent.</p>
+ *
+ * <p>A Type also supports inclusion of level of detail (LOD) or cube map
+ * faces. LOD and cube map faces are booleans to indicate present or not
+ * present. </p>
+ *
+ * <p>A Type also supports YUV format information to support an {@link
+ * androidx.renderscript.Allocation} in a YUV format. The YUV formats
+ * supported are {@link android.graphics.ImageFormat#YV12} and {@link
+ * android.graphics.ImageFormat#NV21}.</p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about creating an application that uses RenderScript,
+ * read the
+ * <a href="{@docRoot}guide/topics/renderscript/index.html">RenderScript</a>
+ * developer guide.</p>
+ * </div>
+ **/
+public class Type extends BaseObj {
+    int mDimX;
+    int mDimY;
+    int mDimZ;
+    boolean mDimMipmaps;
+    boolean mDimFaces;
+    int mDimYuv;
+    int mElementCount;
+    Element mElement;
+
+    public enum CubemapFace {
+        POSITIVE_X (0),
+        NEGATIVE_X (1),
+        POSITIVE_Y (2),
+        NEGATIVE_Y (3),
+        POSITIVE_Z (4),
+        NEGATIVE_Z (5);
+
+        int mID;
+        CubemapFace(int id) {
+            mID = id;
+        }
+    }
+
+    /**
+     * Return the element associated with this Type.
+     *
+     * @return Element
+     */
+    public Element getElement() {
+        return mElement;
+    }
+
+    /**
+     * Return the value of the X dimension.
+     *
+     * @return int
+     */
+    public int getX() {
+        return mDimX;
+    }
+
+    /**
+     * Return the value of the Y dimension or 0 for a 1D allocation.
+     *
+     * @return int
+     */
+    public int getY() {
+        return mDimY;
+    }
+
+    /**
+     * Return the value of the Z dimension or 0 for a 1D or 2D allocation.
+     *
+     * @return int
+     */
+    public int getZ() {
+        return mDimZ;
+    }
+
+    /**
+     * Get the YUV format
+     *
+     * @return int
+     */
+    public int getYuv() {
+        return mDimYuv;
+    }
+
+    /**
+     * Return if the Type has a mipmap chain.
+     *
+     * @return boolean
+     */
+    public boolean hasMipmaps() {
+        return mDimMipmaps;
+    }
+
+    /**
+     * Return if the Type is a cube map.
+     *
+     * @return boolean
+     */
+    public boolean hasFaces() {
+        return mDimFaces;
+    }
+
+    /**
+     * Return the total number of accessable cells in the Type.
+     *
+     * @return int
+     */
+    public int getCount() {
+        return mElementCount;
+    }
+
+    void calcElementCount() {
+        boolean hasLod = hasMipmaps();
+        int x = getX();
+        int y = getY();
+        int z = getZ();
+        int faces = 1;
+        if (hasFaces()) {
+            faces = 6;
+        }
+        if (x == 0) {
+            x = 1;
+        }
+        if (y == 0) {
+            y = 1;
+        }
+        if (z == 0) {
+            z = 1;
+        }
+
+        int count = x * y * z * faces;
+
+        while (hasLod && ((x > 1) || (y > 1) || (z > 1))) {
+            if(x > 1) {
+                x >>= 1;
+            }
+            if(y > 1) {
+                y >>= 1;
+            }
+            if(z > 1) {
+                z >>= 1;
+            }
+
+            count += x * y * z * faces;
+        }
+        mElementCount = count;
+    }
+
+
+    Type(long id, RenderScript rs) {
+        super(id, rs);
+    }
+
+    /*
+     * Get an identical dummy Type for Compat Context
+     *
+     */
+    public long getDummyType(RenderScript mRS, long eid) {
+        return mRS.nIncTypeCreate(eid, mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mDimYuv);
+    }
+
+    /**
+     * Utility function for creating basic 1D types. The type is
+     * created without mipmaps enabled.
+     *
+     * @param rs The RenderScript context
+     * @param e The Element for the Type
+     * @param dimX The X dimension, must be > 0
+     *
+     * @return Type
+     */
+    static public Type createX(RenderScript rs, Element e, int dimX) {
+        if (dimX < 1) {
+            throw new RSInvalidStateException("Dimension must be >= 1.");
+        }
+
+        long id = rs.nTypeCreate(e.getID(rs), dimX, 0, 0, false, false, 0);
+        Type t = new Type(id, rs);
+        t.mElement = e;
+        t.mDimX = dimX;
+        t.calcElementCount();
+        return t;
+    }
+
+    /**
+     * Utility function for creating basic 2D types. The type is
+     * created without mipmaps or cubemaps.
+     *
+     * @param rs The RenderScript context
+     * @param e The Element for the Type
+     * @param dimX The X dimension, must be > 0
+     * @param dimY The Y dimension, must be > 0
+     *
+     * @return Type
+     */
+    static public Type createXY(RenderScript rs, Element e, int dimX, int dimY) {
+        if ((dimX < 1) || (dimY < 1)) {
+            throw new RSInvalidStateException("Dimension must be >= 1.");
+        }
+
+        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, 0, false, false, 0);
+        Type t = new Type(id, rs);
+        t.mElement = e;
+        t.mDimX = dimX;
+        t.mDimY = dimY;
+        t.calcElementCount();
+        return t;
+    }
+
+    /**
+     * Utility function for creating basic 3D types. The type is
+     * created without mipmaps.
+     *
+     * @param rs The RenderScript context
+     * @param e The Element for the Type
+     * @param dimX The X dimension, must be > 0
+     * @param dimY The Y dimension, must be > 0
+     * @param dimZ The Z dimension, must be > 0
+     *
+     * @return Type
+     */
+    static public Type createXYZ(RenderScript rs, Element e, int dimX, int dimY, int dimZ) {
+        if ((dimX < 1) || (dimY < 1) || (dimZ < 1)) {
+            throw new RSInvalidStateException("Dimension must be >= 1.");
+        }
+
+        long id = rs.nTypeCreate(e.getID(rs), dimX, dimY, dimZ, false, false, 0);
+        Type t = new Type(id, rs);
+        t.mElement = e;
+        t.mDimX = dimX;
+        t.mDimY = dimY;
+        t.mDimZ = dimZ;
+        t.calcElementCount();
+        return t;
+    }
+
+    /**
+     * Builder class for Type.
+     *
+     */
+    public static class Builder {
+        RenderScript mRS;
+        int mDimX = 1;
+        int mDimY;
+        int mDimZ;
+        boolean mDimMipmaps;
+        boolean mDimFaces;
+        int mYuv;
+
+        Element mElement;
+
+        /**
+         * Create a new builder object.
+         *
+         * @param rs
+         * @param e The element for the type to be created.
+         */
+        public Builder(RenderScript rs, Element e) {
+            e.checkValid();
+            mRS = rs;
+            mElement = e;
+        }
+
+        /**
+         * Add a dimension to the Type.
+         *
+         *
+         * @param value
+         */
+        public Builder setX(int value) {
+            if(value < 1) {
+                throw new RSIllegalArgumentException("Values of less than 1 for Dimension X are not valid.");
+            }
+            mDimX = value;
+            return this;
+        }
+
+        public Builder setY(int value) {
+            if(value < 1) {
+                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Y are not valid.");
+            }
+            mDimY = value;
+            return this;
+        }
+
+        public Builder setZ(int value) {
+            if(value < 1) {
+                throw new RSIllegalArgumentException("Values of less than 1 for Dimension Z are not valid.");
+            }
+            mDimZ = value;
+            return this;
+        }
+
+        public Builder setMipmaps(boolean value) {
+            mDimMipmaps = value;
+            return this;
+        }
+
+        public Builder setFaces(boolean value) {
+            mDimFaces = value;
+            return this;
+        }
+
+        /**
+         * Set the YUV layout for a Type.
+         *
+         * @param yuvFormat {@link android.graphics.ImageFormat#YV12} or {@link android.graphics.ImageFormat#NV21}
+         */
+        public Builder setYuvFormat(int yuvFormat) {
+            switch (yuvFormat) {
+            case android.graphics.ImageFormat.NV21:
+            case android.graphics.ImageFormat.YV12:
+                break;
+
+            default:
+                throw new RSIllegalArgumentException("Only NV21 and YV12 are supported..");
+            }
+
+            mYuv = yuvFormat;
+            return this;
+        }
+
+
+        /**
+         * Validate structure and create a new Type.
+         *
+         * @return Type
+         */
+        public Type create() {
+            if (mDimZ > 0) {
+                if ((mDimX < 1) || (mDimY < 1)) {
+                    throw new RSInvalidStateException("Both X and Y dimension required when Z is present.");
+                }
+                if (mDimFaces) {
+                    throw new RSInvalidStateException("Cube maps not supported with 3D types.");
+                }
+            }
+            if (mDimY > 0) {
+                if (mDimX < 1) {
+                    throw new RSInvalidStateException("X dimension required when Y is present.");
+                }
+            }
+            if (mDimFaces) {
+                if (mDimY < 1) {
+                    throw new RSInvalidStateException("Cube maps require 2D Types.");
+                }
+            }
+
+            if (mYuv != 0) {
+                if ((mDimZ != 0) || mDimFaces || mDimMipmaps) {
+                    throw new RSInvalidStateException("YUV only supports basic 2D.");
+                }
+            }
+
+            Type t;
+            long id = mRS.nTypeCreate(mElement.getID(mRS),
+                                     mDimX, mDimY, mDimZ, mDimMipmaps, mDimFaces, mYuv);
+            t = new Type(id, mRS);
+
+            t.mElement = mElement;
+            t.mDimX = mDimX;
+            t.mDimY = mDimY;
+            t.mDimZ = mDimZ;
+            t.mDimMipmaps = mDimMipmaps;
+            t.mDimFaces = mDimFaces;
+            t.mDimYuv = mYuv;
+
+            t.calcElementCount();
+            return t;
+        }
+    }
+
+}
diff --git a/androidx/window/extensions/ExtensionHelper.java b/androidx/window/extensions/ExtensionHelper.java
new file mode 100644
index 0000000..c4f11a0
--- /dev/null
+++ b/androidx/window/extensions/ExtensionHelper.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2020 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 androidx.window.extensions;
+
+import static android.view.Display.INVALID_DISPLAY;
+import static android.view.Surface.ROTATION_0;
+import static android.view.Surface.ROTATION_180;
+import static android.view.Surface.ROTATION_270;
+import static android.view.Surface.ROTATION_90;
+
+import android.app.Activity;
+import android.app.ActivityThread;
+import android.graphics.Rect;
+import android.hardware.display.DisplayManagerGlobal;
+import android.os.IBinder;
+import android.view.DisplayInfo;
+import android.view.Surface;
+
+/**
+ * Toolkit class for calculation of the display feature bounds within the window.
+ * NOTE: This sample implementation only works for Activity windows, because there is no public APIs
+ * to obtain layout params or bounds for arbitrary windows.
+ */
+class ExtensionHelper {
+    /**
+     * Rotate the input rectangle specified in default display orientation to the current display
+     * rotation.
+     */
+    static void rotateRectToDisplayRotation(Rect inOutRect, int displayId) {
+        DisplayManagerGlobal dmGlobal = DisplayManagerGlobal.getInstance();
+        DisplayInfo displayInfo = dmGlobal.getDisplayInfo(displayId);
+        int rotation = displayInfo.rotation;
+
+        boolean isSideRotation = rotation == ROTATION_90 || rotation == ROTATION_270;
+        int displayWidth = isSideRotation ? displayInfo.logicalHeight : displayInfo.logicalWidth;
+        int displayHeight = isSideRotation ? displayInfo.logicalWidth : displayInfo.logicalHeight;
+
+        inOutRect.intersect(0, 0, displayWidth, displayHeight);
+
+        rotateBounds(inOutRect, displayWidth, displayHeight, rotation);
+    }
+
+    /**
+     * Rotate the input rectangle within parent bounds for a given delta.
+     */
+    private static void rotateBounds(Rect inOutRect, int parentWidth, int parentHeight,
+            @Surface.Rotation int delta) {
+        int origLeft = inOutRect.left;
+        switch (delta) {
+            case ROTATION_0:
+                return;
+            case ROTATION_90:
+                inOutRect.left = inOutRect.top;
+                inOutRect.top = parentWidth - inOutRect.right;
+                inOutRect.right = inOutRect.bottom;
+                inOutRect.bottom = parentWidth - origLeft;
+                return;
+            case ROTATION_180:
+                inOutRect.left = parentWidth - inOutRect.right;
+                inOutRect.right = parentWidth - origLeft;
+                return;
+            case ROTATION_270:
+                inOutRect.left = parentHeight - inOutRect.bottom;
+                inOutRect.bottom = inOutRect.right;
+                inOutRect.right = parentHeight - inOutRect.top;
+                inOutRect.top = origLeft;
+                return;
+        }
+    }
+
+    /** Transform rectangle from absolute coordinate space to the window coordinate space. */
+    static void transformToWindowSpaceRect(Rect inOutRect, IBinder windowToken) {
+        Rect windowRect = getWindowRect(windowToken);
+        if (windowRect == null) {
+            inOutRect.setEmpty();
+            return;
+        }
+        if (!Rect.intersects(inOutRect, windowRect)) {
+            inOutRect.setEmpty();
+            return;
+        }
+        inOutRect.intersect(windowRect);
+        inOutRect.offset(-windowRect.left, -windowRect.top);
+    }
+
+    /**
+     * Get the current window bounds in absolute coordinates.
+     * NOTE: Only works with Activity windows.
+     */
+    private static Rect getWindowRect(IBinder windowToken) {
+        Activity activity = ActivityThread.currentActivityThread().getActivity(windowToken);
+        final Rect windowRect = new Rect();
+        if (activity != null) {
+            activity.getWindow().getDecorView().getWindowDisplayFrame(windowRect);
+        }
+        return windowRect;
+    }
+
+    /**
+     * Check if this window is an Activity window that is in multi-window mode.
+     */
+    static boolean isInMultiWindow(IBinder windowToken) {
+        Activity activity = ActivityThread.currentActivityThread().getActivity(windowToken);
+        return activity != null && activity.isInMultiWindowMode();
+    }
+
+    /**
+     * Get the id of the parent display for the window.
+     * NOTE: Only works with Activity windows.
+     */
+    static int getWindowDisplay(IBinder windowToken) {
+        Activity activity = ActivityThread.currentActivityThread().getActivity(windowToken);
+        return activity != null
+                ? activity.getWindowManager().getDefaultDisplay().getDisplayId() : INVALID_DISPLAY;
+    }
+}
diff --git a/androidx/window/extensions/ExtensionProvider.java b/androidx/window/extensions/ExtensionProvider.java
new file mode 100644
index 0000000..47349f1
--- /dev/null
+++ b/androidx/window/extensions/ExtensionProvider.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2020 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 androidx.window.extensions;
+
+import android.content.Context;
+
+/**
+ * Provider class that will instantiate the library implementation. It must be included in the
+ * vendor library, and the vendor implementation must match the signature of this class.
+ */
+public class ExtensionProvider {
+
+    /**
+     * The support library will instantiate the vendor implementation using this interface.
+     * @return An implementation of {@link ExtensionInterface}.
+     */
+    public static ExtensionInterface getExtensionImpl(Context context) {
+        return new SettingsExtensionImpl(context);
+    }
+
+    /**
+     * The support library will use this method to check API version compatibility.
+     * @return API version string in MAJOR.MINOR.PATCH-description format.
+     */
+    public static String getApiVersion() {
+        return "1.0.0-settings_sample";
+    }
+}
diff --git a/androidx/window/extensions/SettingsExtensionImpl.java b/androidx/window/extensions/SettingsExtensionImpl.java
new file mode 100644
index 0000000..7a3fbf3
--- /dev/null
+++ b/androidx/window/extensions/SettingsExtensionImpl.java
@@ -0,0 +1,217 @@
+/*
+ * Copyright 2020 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 androidx.window.extensions;
+
+import static android.view.Display.DEFAULT_DISPLAY;
+
+import static androidx.window.extensions.ExtensionHelper.getWindowDisplay;
+import static androidx.window.extensions.ExtensionHelper.isInMultiWindow;
+import static androidx.window.extensions.ExtensionHelper.rotateRectToDisplayRotation;
+import static androidx.window.extensions.ExtensionHelper.transformToWindowSpaceRect;
+
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+class SettingsExtensionImpl extends StubExtension {
+    private static final String TAG = "SettingsExtension";
+
+    private static final String DEVICE_POSTURE = "device_posture";
+    private static final String DISPLAY_FEATURES = "display_features";
+
+    private static final Pattern FEATURE_PATTERN =
+            Pattern.compile("([a-z]+)-\\[(\\d+),(\\d+),(\\d+),(\\d+)]");
+
+    private static final String FEATURE_TYPE_FOLD = "fold";
+    private static final String FEATURE_TYPE_HINGE = "hinge";
+
+    private Context mContext;
+    private SettingsObserver mSettingsObserver;
+
+    final class SettingsObserver extends ContentObserver {
+        private final Uri mDevicePostureUri =
+                Settings.Global.getUriFor(DEVICE_POSTURE);
+        private final Uri mDisplayFeaturesUri =
+                Settings.Global.getUriFor(DISPLAY_FEATURES);
+        private final ContentResolver mResolver = mContext.getContentResolver();
+        private boolean mRegisteredObservers;
+
+
+        private SettingsObserver() {
+            super(new Handler(Looper.getMainLooper()));
+        }
+
+        private void registerObserversIfNeeded() {
+            if (mRegisteredObservers) {
+                return;
+            }
+            mRegisteredObservers = true;
+            mResolver.registerContentObserver(mDevicePostureUri, false /* notifyForDescendents */,
+                    this /* ContentObserver */);
+            mResolver.registerContentObserver(mDisplayFeaturesUri, false /* notifyForDescendents */,
+                    this /* ContentObserver */);
+        }
+
+        private void unregisterObserversIfNeeded() {
+            if (!mRegisteredObservers) {
+                return;
+            }
+            mRegisteredObservers = false;
+            mResolver.unregisterContentObserver(this);
+        }
+
+        @Override
+        public void onChange(boolean selfChange, Uri uri) {
+            if (uri == null) {
+                return;
+            }
+
+            if (mDevicePostureUri.equals(uri)) {
+                updateDevicePosture();
+                return;
+            }
+            if (mDisplayFeaturesUri.equals(uri)) {
+                updateDisplayFeatures();
+                return;
+            }
+        }
+    }
+
+    SettingsExtensionImpl(Context context) {
+        mContext = context;
+        mSettingsObserver = new SettingsObserver();
+    }
+
+    private void updateDevicePosture() {
+        updateDeviceState(getDeviceState());
+    }
+
+    /** Update display features with values read from settings. */
+    private void updateDisplayFeatures() {
+        for (IBinder windowToken : getWindowsListeningForLayoutChanges()) {
+            ExtensionWindowLayoutInfo newLayout = getWindowLayoutInfo(windowToken);
+            updateWindowLayout(windowToken, newLayout);
+        }
+    }
+
+    @NonNull
+    @Override
+    public ExtensionDeviceState getDeviceState() {
+        ContentResolver resolver = mContext.getContentResolver();
+        int posture = Settings.Global.getInt(resolver, DEVICE_POSTURE,
+                ExtensionDeviceState.POSTURE_UNKNOWN);
+        return new ExtensionDeviceState(posture);
+    }
+
+    @NonNull
+    @Override
+    public ExtensionWindowLayoutInfo getWindowLayoutInfo(@NonNull IBinder windowToken) {
+        List<ExtensionDisplayFeature> displayFeatures = readDisplayFeatures(windowToken);
+        return new ExtensionWindowLayoutInfo(displayFeatures);
+    }
+
+    private List<ExtensionDisplayFeature> readDisplayFeatures(IBinder windowToken) {
+        List<ExtensionDisplayFeature> features = new ArrayList<ExtensionDisplayFeature>();
+        int displayId = getWindowDisplay(windowToken);
+        if (displayId != DEFAULT_DISPLAY) {
+            Log.w(TAG, "This sample doesn't support display features on secondary displays");
+            return features;
+        }
+
+        ContentResolver resolver = mContext.getContentResolver();
+        final String displayFeaturesString = Settings.Global.getString(resolver, DISPLAY_FEATURES);
+        if (isInMultiWindow(windowToken)) {
+            // It is recommended not to report any display features in multi-window mode, since it
+            // won't be possible to synchronize the display feature positions with window movement.
+            return features;
+        }
+        if (TextUtils.isEmpty(displayFeaturesString)) {
+            return features;
+        }
+
+        String[] featureStrings = displayFeaturesString.split(";");
+        for (String featureString : featureStrings) {
+            Matcher featureMatcher = FEATURE_PATTERN.matcher(featureString);
+            if (!featureMatcher.matches()) {
+                Log.e(TAG, "Malformed feature description format: " + featureString);
+                continue;
+            }
+            try {
+                String featureType = featureMatcher.group(1);
+                int type;
+                switch (featureType) {
+                    case FEATURE_TYPE_FOLD:
+                        type = ExtensionDisplayFeature.TYPE_FOLD;
+                        break;
+                    case FEATURE_TYPE_HINGE:
+                        type = ExtensionDisplayFeature.TYPE_HINGE;
+                        break;
+                    default: {
+                        Log.e(TAG, "Malformed feature type: " + featureType);
+                        continue;
+                    }
+                }
+
+                int left = Integer.parseInt(featureMatcher.group(2));
+                int top = Integer.parseInt(featureMatcher.group(3));
+                int right = Integer.parseInt(featureMatcher.group(4));
+                int bottom = Integer.parseInt(featureMatcher.group(5));
+                Rect featureRect = new Rect(left, top, right, bottom);
+                rotateRectToDisplayRotation(featureRect, displayId);
+                transformToWindowSpaceRect(featureRect, windowToken);
+                if (!featureRect.isEmpty()) {
+                    ExtensionDisplayFeature feature =
+                            new ExtensionDisplayFeature(featureRect, type);
+                    features.add(feature);
+                } else {
+                    Log.w(TAG, "Failed to adjust feature to window");
+                }
+            } catch (NumberFormatException e) {
+                Log.e(TAG, "Malformed feature description: " + featureString);
+            }
+        }
+        return features;
+    }
+
+    @Override
+    protected void onListenersChanged() {
+        if (mSettingsObserver == null) {
+            return;
+        }
+
+        if (hasListeners()) {
+            mSettingsObserver.registerObserversIfNeeded();
+        } else {
+            mSettingsObserver.unregisterObserversIfNeeded();
+        }
+    }
+}
