diff options
40 files changed, 3082 insertions, 48 deletions
diff --git a/cmds/bootanimation/AudioPlayer.cpp b/cmds/bootanimation/AudioPlayer.cpp index 81fe5f8..2932130 100644 --- a/cmds/bootanimation/AudioPlayer.cpp +++ b/cmds/bootanimation/AudioPlayer.cpp @@ -305,7 +305,7 @@ bool AudioPlayer::threadLoop() exit: if (pcm) pcm_close(pcm); - mCurrentFile->release(); + delete mCurrentFile; mCurrentFile = NULL; return false; } diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp index 1d4de22..bb25ec6 100644 --- a/cmds/bootanimation/BootAnimation.cpp +++ b/cmds/bootanimation/BootAnimation.cpp @@ -179,7 +179,7 @@ status_t BootAnimation::initTexture(const Animation::Frame& frame) // FileMap memory is never released until application exit. // Release it now as the texture is already loaded and the memory used for // the packed resource can be released. - frame.map->release(); + delete frame.map; // ensure we can call getPixels(). No need to call unlock, since the // bitmap will go out of scope when we return from this method. @@ -446,7 +446,7 @@ bool BootAnimation::readFile(const char* name, String8& outString) } outString.setTo((char const*)entryMap->getDataPtr(), entryMap->getDataLength()); - entryMap->release(); + delete entryMap; return true; } diff --git a/cmds/idmap/scan.cpp b/cmds/idmap/scan.cpp index bbe6eef..197e36b 100644 --- a/cmds/idmap/scan.cpp +++ b/cmds/idmap/scan.cpp @@ -147,20 +147,20 @@ namespace { char *buf = new char[uncompLen]; if (NULL == buf) { ALOGW("%s: failed to allocate %zd byte\n", __FUNCTION__, uncompLen); - dataMap->release(); + delete dataMap; return -1; } StreamingZipInflater inflater(dataMap, uncompLen); if (inflater.read(buf, uncompLen) < 0) { ALOGW("%s: failed to inflate %zd byte\n", __FUNCTION__, uncompLen); delete[] buf; - dataMap->release(); + delete dataMap; return -1; } int priority = parse_manifest(buf, uncompLen, target_package_name); delete[] buf; - dataMap->release(); + delete dataMap; return priority; } } diff --git a/core/java/android/content/SharedPreferences.java b/core/java/android/content/SharedPreferences.java index 46c9234..462f473 100644 --- a/core/java/android/content/SharedPreferences.java +++ b/core/java/android/content/SharedPreferences.java @@ -71,9 +71,7 @@ public interface SharedPreferences { * {@link #commit} or {@link #apply} are called. * * @param key The name of the preference to modify. - * @param value The new value for the preference. Supplying {@code null} - * as the value is equivalent to calling {@link #remove(String)} with - * this key. + * @param value The new value for the preference. * * @return Returns a reference to the same Editor object, so you can * chain put calls together. diff --git a/core/java/android/os/UEventObserver.java b/core/java/android/os/UEventObserver.java index 9dbfd50..5c80ca6 100644 --- a/core/java/android/os/UEventObserver.java +++ b/core/java/android/os/UEventObserver.java @@ -22,13 +22,13 @@ import java.util.ArrayList; import java.util.HashMap; /** - * UEventObserver is an abstract class that receives UEvent's from the kernel.<p> + * UEventObserver is an abstract class that receives UEvents from the kernel.<p> * * Subclass UEventObserver, implementing onUEvent(UEvent event), then call * startObserving() with a match string. The UEvent thread will then call your * onUEvent() method when a UEvent occurs that contains your match string.<p> * - * Call stopObserving() to stop receiving UEvent's.<p> + * Call stopObserving() to stop receiving UEvents.<p> * * There is only one UEvent thread per process, even if that process has * multiple UEventObserver subclass instances. The UEvent thread starts when @@ -78,7 +78,7 @@ public abstract class UEventObserver { } /** - * Begin observation of UEvent's.<p> + * Begin observation of UEvents.<p> * This method will cause the UEvent thread to start if this is the first * invocation of startObserving in this process.<p> * Once called, the UEvent thread will call onUEvent() when an incoming @@ -103,7 +103,7 @@ public abstract class UEventObserver { } /** - * End observation of UEvent's.<p> + * End observation of UEvents.<p> * This process's UEvent thread will never call onUEvent() on this * UEventObserver after this call. Repeated calls have no effect. */ diff --git a/core/java/android/security/IKeystoreService.aidl b/core/java/android/security/IKeystoreService.aidl index bf51ed1..ac6bbb7 100644 --- a/core/java/android/security/IKeystoreService.aidl +++ b/core/java/android/security/IKeystoreService.aidl @@ -16,6 +16,10 @@ package android.security; +import android.security.keymaster.ExportResult; +import android.security.keymaster.KeyCharacteristics; +import android.security.keymaster.KeymasterArguments; +import android.security.keymaster.OperationResult; import android.security.KeystoreArguments; /** @@ -52,4 +56,19 @@ interface IKeystoreService { int reset_uid(int uid); int sync_uid(int sourceUid, int targetUid); int password_uid(String password, int uid); + + // Keymaster 0.4 methods + int addRngEntropy(in byte[] data); + int generateKey(String alias, in KeymasterArguments arguments, int uid, int flags, + out KeyCharacteristics characteristics); + int getKeyCharacteristics(String alias, in byte[] clientId, + in byte[] appId, out KeyCharacteristics characteristics); + int importKey(String alias, in KeymasterArguments arguments, int format, + in byte[] keyData, int uid, int flags, out KeyCharacteristics characteristics); + ExportResult exportKey(String alias, int format, in byte[] clientId, in byte[] appId); + OperationResult begin(IBinder appToken, String alias, int purpose, boolean pruneable, + in KeymasterArguments params, out KeymasterArguments operationParams); + OperationResult update(IBinder token, in KeymasterArguments params, in byte[] input); + OperationResult finish(IBinder token, in KeymasterArguments params, in byte[] signature); + int abort(IBinder handle); } diff --git a/core/java/android/security/keymaster/ExportResult.aidl b/core/java/android/security/keymaster/ExportResult.aidl new file mode 100644 index 0000000..f522355 --- /dev/null +++ b/core/java/android/security/keymaster/ExportResult.aidl @@ -0,0 +1,20 @@ +/** + * 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 android.security.keymaster; + +/* @hide */ +parcelable ExportResult; diff --git a/core/java/android/security/keymaster/ExportResult.java b/core/java/android/security/keymaster/ExportResult.java new file mode 100644 index 0000000..bb44c03 --- /dev/null +++ b/core/java/android/security/keymaster/ExportResult.java @@ -0,0 +1,56 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * Class for handling parceling the return values from keymaster's export operation. + * @hide + */ +public class ExportResult implements Parcelable { + public final int resultCode; + public final byte[] exportData; + + public static final Parcelable.Creator<ExportResult> CREATOR = new + Parcelable.Creator<ExportResult>() { + public ExportResult createFromParcel(Parcel in) { + return new ExportResult(in); + } + + public ExportResult[] newArray(int length) { + return new ExportResult[length]; + } + }; + + protected ExportResult(Parcel in) { + resultCode = in.readInt(); + exportData = in.createByteArray(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(resultCode); + out.writeByteArray(exportData); + } +}; diff --git a/core/java/android/security/keymaster/KeyCharacteristics.aidl b/core/java/android/security/keymaster/KeyCharacteristics.aidl new file mode 100644 index 0000000..15014b1 --- /dev/null +++ b/core/java/android/security/keymaster/KeyCharacteristics.aidl @@ -0,0 +1,20 @@ +/** + * 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 android.security.keymaster; + +/* @hide */ +parcelable KeyCharacteristics; diff --git a/core/java/android/security/keymaster/KeyCharacteristics.java b/core/java/android/security/keymaster/KeyCharacteristics.java new file mode 100644 index 0000000..b803a1b --- /dev/null +++ b/core/java/android/security/keymaster/KeyCharacteristics.java @@ -0,0 +1,63 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.List; + +/** + * @hide + */ +public class KeyCharacteristics implements Parcelable { + public KeymasterArguments swEnforced; + public KeymasterArguments hwEnforced; + + public static final Parcelable.Creator<KeyCharacteristics> CREATOR = new + Parcelable.Creator<KeyCharacteristics>() { + public KeyCharacteristics createFromParcel(Parcel in) { + return new KeyCharacteristics(in); + } + + public KeyCharacteristics[] newArray(int length) { + return new KeyCharacteristics[length]; + } + }; + + public KeyCharacteristics() {} + + protected KeyCharacteristics(Parcel in) { + readFromParcel(in); + } + + @Override + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel out, int flags) { + swEnforced.writeToParcel(out, flags); + hwEnforced.writeToParcel(out, flags); + } + + public void readFromParcel(Parcel in) { + swEnforced = KeymasterArguments.CREATOR.createFromParcel(in); + hwEnforced = KeymasterArguments.CREATOR.createFromParcel(in); + } +} + diff --git a/core/java/android/security/keymaster/KeymasterArgument.java b/core/java/android/security/keymaster/KeymasterArgument.java new file mode 100644 index 0000000..9a1c894 --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterArgument.java @@ -0,0 +1,81 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; +import android.os.ParcelFormatException; + +/** + * Base class for the Java side of a Keymaster tagged argument. + * <p> + * Serialization code for this and subclasses must be kept in sync with system/security/keystore + * and with hardware/libhardware/include/hardware/keymaster_defs.h + * @hide + */ +abstract class KeymasterArgument implements Parcelable { + public final int tag; + + public static final Parcelable.Creator<KeymasterArgument> CREATOR = new + Parcelable.Creator<KeymasterArgument>() { + public KeymasterArgument createFromParcel(Parcel in) { + final int pos = in.dataPosition(); + final int tag = in.readInt(); + switch (KeymasterDefs.getTagType(tag)) { + case KeymasterDefs.KM_ENUM: + case KeymasterDefs.KM_ENUM_REP: + case KeymasterDefs.KM_INT: + case KeymasterDefs.KM_INT_REP: + return new KeymasterIntArgument(tag, in); + case KeymasterDefs.KM_LONG: + return new KeymasterLongArgument(tag, in); + case KeymasterDefs.KM_DATE: + return new KeymasterDateArgument(tag, in); + case KeymasterDefs.KM_BYTES: + case KeymasterDefs.KM_BIGNUM: + return new KeymasterBlobArgument(tag, in); + case KeymasterDefs.KM_BOOL: + return new KeymasterBooleanArgument(tag, in); + default: + throw new ParcelFormatException("Bad tag: " + tag + " at " + pos); + } + } + public KeymasterArgument[] newArray(int size) { + return new KeymasterArgument[size]; + } + }; + + protected KeymasterArgument(int tag) { + this.tag = tag; + } + + /** + * Writes the value of this argument, if any, to the provided parcel. + */ + public abstract void writeValue(Parcel out); + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(tag); + writeValue(out); + } +} diff --git a/core/java/android/security/keymaster/KeymasterArguments.aidl b/core/java/android/security/keymaster/KeymasterArguments.aidl new file mode 100644 index 0000000..7aef5a6 --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterArguments.aidl @@ -0,0 +1,20 @@ +/** + * 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 android.security.keymaster; + +/* @hide */ +parcelable KeymasterArguments; diff --git a/core/java/android/security/keymaster/KeymasterArguments.java b/core/java/android/security/keymaster/KeymasterArguments.java new file mode 100644 index 0000000..b5fd4bd --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterArguments.java @@ -0,0 +1,186 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +/** + * Utility class for the java side of user specified Keymaster arguments. + * <p> + * Serialization code for this and subclasses must be kept in sync with system/security/keystore + * @hide + */ +public class KeymasterArguments implements Parcelable { + List<KeymasterArgument> mArguments; + + public static final Parcelable.Creator<KeymasterArguments> CREATOR = new + Parcelable.Creator<KeymasterArguments>() { + public KeymasterArguments createFromParcel(Parcel in) { + return new KeymasterArguments(in); + } + public KeymasterArguments[] newArray(int size) { + return new KeymasterArguments[size]; + } + }; + + public KeymasterArguments() { + mArguments = new ArrayList<KeymasterArgument>(); + } + + private KeymasterArguments(Parcel in) { + mArguments = in.createTypedArrayList(KeymasterArgument.CREATOR); + } + + public void addInt(int tag, int value) { + mArguments.add(new KeymasterIntArgument(tag, value)); + } + + public void addBoolean(int tag) { + mArguments.add(new KeymasterBooleanArgument(tag)); + } + + public void addLong(int tag, long value) { + mArguments.add(new KeymasterLongArgument(tag, value)); + } + + public void addBlob(int tag, byte[] value) { + mArguments.add(new KeymasterBlobArgument(tag, value)); + } + + public void addDate(int tag, Date value) { + mArguments.add(new KeymasterDateArgument(tag, value)); + } + + private KeymasterArgument getArgumentByTag(int tag) { + for (KeymasterArgument arg : mArguments) { + if (arg.tag == tag) { + return arg; + } + } + return null; + } + + public boolean containsTag(int tag) { + return getArgumentByTag(tag) != null; + } + + public int getInt(int tag, int defaultValue) { + switch (KeymasterDefs.getTagType(tag)) { + case KeymasterDefs.KM_ENUM: + case KeymasterDefs.KM_INT: + break; // Accepted types + case KeymasterDefs.KM_INT_REP: + case KeymasterDefs.KM_ENUM_REP: + throw new IllegalArgumentException("Repeatable tags must use getInts: " + tag); + default: + throw new IllegalArgumentException("Tag is not an int type: " + tag); + } + KeymasterArgument arg = getArgumentByTag(tag); + if (arg == null) { + return defaultValue; + } + return ((KeymasterIntArgument) arg).value; + } + + public long getLong(int tag, long defaultValue) { + if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_LONG) { + throw new IllegalArgumentException("Tag is not a long type: " + tag); + } + KeymasterArgument arg = getArgumentByTag(tag); + if (arg == null) { + return defaultValue; + } + return ((KeymasterLongArgument) arg).value; + } + + public Date getDate(int tag, Date defaultValue) { + if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_DATE) { + throw new IllegalArgumentException("Tag is not a date type: " + tag); + } + KeymasterArgument arg = getArgumentByTag(tag); + if (arg == null) { + return defaultValue; + } + return ((KeymasterDateArgument) arg).date; + } + + public boolean getBoolean(int tag, boolean defaultValue) { + if (KeymasterDefs.getTagType(tag) != KeymasterDefs.KM_BOOL) { + throw new IllegalArgumentException("Tag is not a boolean type: " + tag); + } + KeymasterArgument arg = getArgumentByTag(tag); + if (arg == null) { + return defaultValue; + } + return true; + } + + public byte[] getBlob(int tag, byte[] defaultValue) { + switch (KeymasterDefs.getTagType(tag)) { + case KeymasterDefs.KM_BYTES: + case KeymasterDefs.KM_BIGNUM: + break; // Allowed types. + default: + throw new IllegalArgumentException("Tag is not a blob type: " + tag); + } + KeymasterArgument arg = getArgumentByTag(tag); + if (arg == null) { + return defaultValue; + } + return ((KeymasterBlobArgument) arg).blob; + } + + public List<Integer> getInts(int tag) { + switch (KeymasterDefs.getTagType(tag)) { + case KeymasterDefs.KM_INT_REP: + case KeymasterDefs.KM_ENUM_REP: + break; // Allowed types. + default: + throw new IllegalArgumentException("Tag is not a repeating type: " + tag); + } + List<Integer> values = new ArrayList<Integer>(); + for (KeymasterArgument arg : mArguments) { + if (arg.tag == tag) { + values.add(((KeymasterIntArgument) arg).value); + } + } + return values; + } + + public int size() { + return mArguments.size(); + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeTypedList(mArguments); + } + + public void readFromParcel(Parcel in) { + in.readTypedList(mArguments, KeymasterArgument.CREATOR); + } + + @Override + public int describeContents() { + return 0; + } +} diff --git a/core/java/android/security/keymaster/KeymasterBlobArgument.java b/core/java/android/security/keymaster/KeymasterBlobArgument.java new file mode 100644 index 0000000..27f1153 --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterBlobArgument.java @@ -0,0 +1,42 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * @hide + */ +class KeymasterBlobArgument extends KeymasterArgument { + public final byte[] blob; + + public KeymasterBlobArgument(int tag, byte[] blob) { + super(tag); + this.blob = blob; + } + + public KeymasterBlobArgument(int tag, Parcel in) { + super(tag); + blob = in.createByteArray(); + } + + @Override + public void writeValue(Parcel out) { + out.writeByteArray(blob); + } +} diff --git a/core/java/android/security/keymaster/KeymasterBooleanArgument.java b/core/java/android/security/keymaster/KeymasterBooleanArgument.java new file mode 100644 index 0000000..8e17db4 --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterBooleanArgument.java @@ -0,0 +1,42 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * @hide + */ +class KeymasterBooleanArgument extends KeymasterArgument { + + // Boolean arguments are always true if they exist and false if they don't. + public final boolean value = true; + + public KeymasterBooleanArgument(int tag) { + super(tag); + } + + public KeymasterBooleanArgument(int tag, Parcel in) { + super(tag); + } + + @Override + public void writeValue(Parcel out) { + // Do nothing, value is implicit. + } +} diff --git a/core/java/android/security/keymaster/KeymasterDateArgument.java b/core/java/android/security/keymaster/KeymasterDateArgument.java new file mode 100644 index 0000000..e8f4055 --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterDateArgument.java @@ -0,0 +1,44 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.Date; + +/** + * @hide + */ +class KeymasterDateArgument extends KeymasterArgument { + public final Date date; + + public KeymasterDateArgument(int tag, Date date) { + super(tag); + this.date = date; + } + + public KeymasterDateArgument(int tag, Parcel in) { + super(tag); + date = new Date(in.readLong()); + } + + @Override + public void writeValue(Parcel out) { + out.writeLong(date.getTime()); + } +} diff --git a/core/java/android/security/keymaster/KeymasterDefs.java b/core/java/android/security/keymaster/KeymasterDefs.java new file mode 100644 index 0000000..88cad79 --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterDefs.java @@ -0,0 +1,227 @@ +/** + * 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 android.security.keymaster; + +/** + * Class tracking all the keymaster enum values needed for the binder API to keystore. + * This must be kept in sync with hardware/libhardware/include/hardware/keymaster_defs.h + * See keymaster_defs.h for detailed descriptions of each constant. + * @hide + */ +public final class KeymasterDefs { + + private KeymasterDefs() {} + + // Tag types. + public static final int KM_INVALID = 0 << 28; + public static final int KM_ENUM = 1 << 28; + public static final int KM_ENUM_REP = 2 << 28; + public static final int KM_INT = 3 << 28; + public static final int KM_INT_REP = 4 << 28; + public static final int KM_LONG = 5 << 28; + public static final int KM_DATE = 6 << 28; + public static final int KM_BOOL = 7 << 28; + public static final int KM_BIGNUM = 8 << 28; + public static final int KM_BYTES = 9 << 28; + + // Tag values. + public static final int KM_TAG_INVALID = KM_INVALID | 0; + public static final int KM_TAG_PURPOSE = KM_ENUM_REP | 1; + public static final int KM_TAG_ALGORITHM = KM_ENUM | 2; + public static final int KM_TAG_KEY_SIZE = KM_INT | 3; + public static final int KM_TAG_BLOCK_MODE = KM_ENUM | 4; + public static final int KM_TAG_DIGEST = KM_ENUM | 5; + public static final int KM_TAG_MAC_LENGTH = KM_INT | 6; + public static final int KM_TAG_PADDING = KM_ENUM | 7; + public static final int KM_TAG_RETURN_UNAUTHED = KM_BOOL | 8; + public static final int KM_TAG_CALLER_NONCE = KM_BOOL | 9; + + public static final int KM_TAG_RESCOPING_ADD = KM_ENUM_REP | 101; + public static final int KM_TAG_RESCOPING_DEL = KM_ENUM_REP | 102; + public static final int KM_TAG_BLOB_USAGE_REQUIREMENTS = KM_ENUM | 705; + + public static final int KM_TAG_RSA_PUBLIC_EXPONENT = KM_LONG | 200; + public static final int KM_TAG_DSA_GENERATOR = KM_BIGNUM | 201; + public static final int KM_TAG_DSA_P = KM_BIGNUM | 202; + public static final int KM_TAG_DSA_Q = KM_BIGNUM | 203; + public static final int KM_TAG_ACTIVE_DATETIME = KM_DATE | 400; + public static final int KM_TAG_ORIGINATION_EXPIRE_DATETIME = KM_DATE | 401; + public static final int KM_TAG_USAGE_EXPIRE_DATETIME = KM_DATE | 402; + public static final int KM_TAG_MIN_SECONDS_BETWEEN_OPS = KM_INT | 403; + public static final int KM_TAG_MAX_USES_PER_BOOT = KM_INT | 404; + + public static final int KM_TAG_ALL_USERS = KM_BOOL | 500; + public static final int KM_TAG_USER_ID = KM_INT | 501; + public static final int KM_TAG_NO_AUTH_REQUIRED = KM_BOOL | 502; + public static final int KM_TAG_USER_AUTH_ID = KM_INT_REP | 503; + public static final int KM_TAG_AUTH_TIMEOUT = KM_INT | 504; + + public static final int KM_TAG_ALL_APPLICATIONS = KM_BOOL | 600; + public static final int KM_TAG_APPLICATION_ID = KM_BYTES | 601; + + public static final int KM_TAG_APPLICATION_DATA = KM_BYTES | 700; + public static final int KM_TAG_CREATION_DATETIME = KM_DATE | 701; + public static final int KM_TAG_ORIGIN = KM_ENUM | 702; + public static final int KM_TAG_ROLLBACK_RESISTANT = KM_BOOL | 703; + public static final int KM_TAG_ROOT_OF_TRUST = KM_BYTES | 704; + + public static final int KM_TAG_ASSOCIATED_DATA = KM_BYTES | 1000; + public static final int KM_TAG_NONCE = KM_BYTES | 1001; + public static final int KM_TAG_CHUNK_LENGTH = KM_INT | 1002; + + // Algorithm values. + public static final int KM_ALGORITHM_RSA = 1; + public static final int KM_ALGORITHM_DSA = 2; + public static final int KM_ALGORITHM_ECDSA = 3; + public static final int KM_ALGORITHM_ECIES = 4; + public static final int KM_ALGORITHM_AES = 32; + public static final int KM_ALGORITHM_3DES = 33; + public static final int KM_ALGORITHM_SKIPJACK = 34; + public static final int KM_ALGORITHM_MARS = 48; + public static final int KM_ALGORITHM_RC6 = 49; + public static final int KM_ALGORITHM_SERPENT = 50; + public static final int KM_ALGORITHM_TWOFISH = 51; + public static final int KM_ALGORITHM_IDEA = 52; + public static final int KM_ALGORITHM_RC5 = 53; + public static final int KM_ALGORITHM_CAST5 = 54; + public static final int KM_ALGORITHM_BLOWFISH = 55; + public static final int KM_ALGORITHM_RC4 = 64; + public static final int KM_ALGORITHM_CHACHA20 = 65; + public static final int KM_ALGORITHM_HMAC = 128; + + // Block modes. + public static final int KM_MODE_FIRST_UNAUTHENTICATED = 1; + public static final int KM_MODE_ECB = KM_MODE_FIRST_UNAUTHENTICATED; + public static final int KM_MODE_CBC = 2; + public static final int KM_MODE_CBC_CTS = 3; + public static final int KM_MODE_CTR = 4; + public static final int KM_MODE_OFB = 5; + public static final int KM_MODE_CFB = 6; + public static final int KM_MODE_XTS = 7; + public static final int KM_MODE_FIRST_AUTHENTICATED = 32; + public static final int KM_MODE_GCM = KM_MODE_FIRST_AUTHENTICATED; + public static final int KM_MODE_OCB = 33; + public static final int KM_MODE_CCM = 34; + public static final int KM_MODE_FIRST_MAC = 128; + public static final int KM_MODE_CMAC = KM_MODE_FIRST_MAC; + public static final int KM_MODE_POLY1305 = 129; + + // Padding modes. + public static final int KM_PAD_NONE = 1; + public static final int KM_PAD_RSA_OAEP = 2; + public static final int KM_PAD_RSA_PSS = 3; + public static final int KM_PAD_RSA_PKCS1_1_5_ENCRYPT = 4; + public static final int KM_PAD_RSA_PKCS1_1_5_SIGN = 5; + public static final int KM_PAD_ANSI_X923 = 32; + public static final int KM_PAD_ISO_10126 = 33; + public static final int KM_PAD_ZERO = 64; + public static final int KM_PAD_PKCS7 = 65; + public static final int KM_PAD_ISO_7816_4 = 66; + + // Digest modes. + public static final int KM_DIGEST_NONE = 0; + public static final int KM_DIGEST_MD5 = 1; + public static final int KM_DIGEST_SHA1 = 2; + public static final int KM_DIGEST_SHA_2_224 = 3; + public static final int KM_DIGEST_SHA_2_256 = 4; + public static final int KM_DIGEST_SHA_2_384 = 5; + public static final int KM_DIGEST_SHA_2_512 = 6; + public static final int KM_DIGEST_SHA_3_256 = 7; + public static final int KM_DIGEST_SHA_3_384 = 8; + public static final int KM_DIGEST_SHA_3_512 = 9; + + // Key origins. + public static final int KM_ORIGIN_HARDWARE = 0; + public static final int KM_ORIGIN_SOFTWARE = 1; + public static final int KM_ORIGIN_IMPORTED = 2; + + // Key usability requirements. + public static final int KM_BLOB_STANDALONE = 0; + public static final int KM_BLOB_REQUIRES_FILE_SYSTEM = 1; + + // Operation Purposes. + public static final int KM_PURPOSE_ENCRYPT = 0; + public static final int KM_PURPOSE_DECRYPT = 1; + public static final int KM_PURPOSE_SIGN = 2; + public static final int KM_PURPOSE_VERIFY = 3; + + // Key formats. + public static final int KM_KEY_FORMAT_X509 = 0; + public static final int KM_KEY_FORMAT_PKCS8 = 1; + public static final int KM_KEY_FORMAT_PKCS12 = 2; + public static final int KM_KEY_FORMAT_RAW = 3; + + // Error codes. + public static final int KM_ERROR_OK = 0; + public static final int KM_ERROR_ROOT_OF_TRUST_ALREADY_SET = -1; + public static final int KM_ERROR_UNSUPPORTED_PURPOSE = -2; + public static final int KM_ERROR_INCOMPATIBLE_PURPOSE = -3; + public static final int KM_ERROR_UNSUPPORTED_ALGORITHM = -4; + public static final int KM_ERROR_INCOMPATIBLE_ALGORITHM = -5; + public static final int KM_ERROR_UNSUPPORTED_KEY_SIZE = -6; + public static final int KM_ERROR_UNSUPPORTED_BLOCK_MODE = -7; + public static final int KM_ERROR_INCOMPATIBLE_BLOCK_MODE = -8; + public static final int KM_ERROR_UNSUPPORTED_TAG_LENGTH = -9; + public static final int KM_ERROR_UNSUPPORTED_PADDING_MODE = -10; + public static final int KM_ERROR_INCOMPATIBLE_PADDING_MODE = -11; + public static final int KM_ERROR_UNSUPPORTED_DIGEST = -12; + public static final int KM_ERROR_INCOMPATIBLE_DIGEST = -13; + public static final int KM_ERROR_INVALID_EXPIRATION_TIME = -14; + public static final int KM_ERROR_INVALID_USER_ID = -15; + public static final int KM_ERROR_INVALID_AUTHORIZATION_TIMEOUT = -16; + public static final int KM_ERROR_UNSUPPORTED_KEY_FORMAT = -17; + public static final int KM_ERROR_INCOMPATIBLE_KEY_FORMAT = -18; + public static final int KM_ERROR_UNSUPPORTED_KEY_ENCRYPTION_ALGORITHM = -19; + public static final int KM_ERROR_UNSUPPORTED_KEY_VERIFICATION_ALGORITHM = -20; + public static final int KM_ERROR_INVALID_INPUT_LENGTH = -21; + public static final int KM_ERROR_KEY_EXPORT_OPTIONS_INVALID = -22; + public static final int KM_ERROR_DELEGATION_NOT_ALLOWED = -23; + public static final int KM_ERROR_KEY_NOT_YET_VALID = -24; + public static final int KM_ERROR_KEY_EXPIRED = -25; + public static final int KM_ERROR_KEY_USER_NOT_AUTHENTICATED = -26; + public static final int KM_ERROR_OUTPUT_PARAMETER_NULL = -27; + public static final int KM_ERROR_INVALID_OPERATION_HANDLE = -28; + public static final int KM_ERROR_INSUFFICIENT_BUFFER_SPACE = -29; + public static final int KM_ERROR_VERIFICATION_FAILED = -30; + public static final int KM_ERROR_TOO_MANY_OPERATIONS = -31; + public static final int KM_ERROR_UNEXPECTED_NULL_POINTER = -32; + public static final int KM_ERROR_INVALID_KEY_BLOB = -33; + public static final int KM_ERROR_IMPORTED_KEY_NOT_ENCRYPTED = -34; + public static final int KM_ERROR_IMPORTED_KEY_DECRYPTION_FAILED = -35; + public static final int KM_ERROR_IMPORTED_KEY_NOT_SIGNED = -36; + public static final int KM_ERROR_IMPORTED_KEY_VERIFICATION_FAILED = -37; + public static final int KM_ERROR_INVALID_ARGUMENT = -38; + public static final int KM_ERROR_UNSUPPORTED_TAG = -39; + public static final int KM_ERROR_INVALID_TAG = -40; + public static final int KM_ERROR_MEMORY_ALLOCATION_FAILED = -41; + public static final int KM_ERROR_INVALID_RESCOPING = -42; + public static final int KM_ERROR_INVALID_DSA_PARAMS = -43; + public static final int KM_ERROR_IMPORT_PARAMETER_MISMATCH = -44; + public static final int KM_ERROR_SECURE_HW_ACCESS_DENIED = -45; + public static final int KM_ERROR_OPERATION_CANCELLED = -46; + public static final int KM_ERROR_CONCURRENT_ACCESS_CONFLICT = -47; + public static final int KM_ERROR_SECURE_HW_BUSY = -48; + public static final int KM_ERROR_SECURE_HW_COMMUNICATION_FAILED = -49; + public static final int KM_ERROR_UNSUPPORTED_EC_FIELD = -50; + public static final int KM_ERROR_UNIMPLEMENTED = -100; + public static final int KM_ERROR_VERSION_MISMATCH = -101; + public static final int KM_ERROR_UNKNOWN_ERROR = -1000; + + public static int getTagType(int tag) { + return tag & (0xF << 28); + } +} diff --git a/core/java/android/security/keymaster/KeymasterIntArgument.java b/core/java/android/security/keymaster/KeymasterIntArgument.java new file mode 100644 index 0000000..71797ae --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterIntArgument.java @@ -0,0 +1,42 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * @hide + */ +class KeymasterIntArgument extends KeymasterArgument { + public final int value; + + public KeymasterIntArgument(int tag, int value) { + super(tag); + this.value = value; + } + + public KeymasterIntArgument(int tag, Parcel in) { + super(tag); + value = in.readInt(); + } + + @Override + public void writeValue(Parcel out) { + out.writeInt(value); + } +} diff --git a/core/java/android/security/keymaster/KeymasterLongArgument.java b/core/java/android/security/keymaster/KeymasterLongArgument.java new file mode 100644 index 0000000..781b1ab --- /dev/null +++ b/core/java/android/security/keymaster/KeymasterLongArgument.java @@ -0,0 +1,42 @@ +/** + * 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 android.security.keymaster; + +import android.os.Parcel; +import android.os.Parcelable; + +/** + * @hide + */ +class KeymasterLongArgument extends KeymasterArgument { + public final long value; + + public KeymasterLongArgument(int tag, long value) { + super(tag); + this.value = value; + } + + public KeymasterLongArgument(int tag, Parcel in) { + super(tag); + value = in.readLong(); + } + + @Override + public void writeValue(Parcel out) { + out.writeLong(value); + } +} diff --git a/core/java/android/security/keymaster/OperationResult.aidl b/core/java/android/security/keymaster/OperationResult.aidl new file mode 100644 index 0000000..699e8d0 --- /dev/null +++ b/core/java/android/security/keymaster/OperationResult.aidl @@ -0,0 +1,20 @@ +/** + * 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 android.security.keymaster; + +/* @hide */ +parcelable OperationResult; diff --git a/core/java/android/security/keymaster/OperationResult.java b/core/java/android/security/keymaster/OperationResult.java new file mode 100644 index 0000000..ad54c96 --- /dev/null +++ b/core/java/android/security/keymaster/OperationResult.java @@ -0,0 +1,66 @@ +/** + * 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 android.security.keymaster; + +import android.os.IBinder; +import android.os.Parcel; +import android.os.Parcelable; + +import java.util.List; + +/** + * Class for handling the parceling of return values from keymaster crypto operations + * (begin/update/finish). + * @hide + */ +public class OperationResult implements Parcelable { + public final int resultCode; + public final IBinder token; + public final int inputConsumed; + public final byte[] output; + + public static final Parcelable.Creator<OperationResult> CREATOR = new + Parcelable.Creator<OperationResult>() { + public OperationResult createFromParcel(Parcel in) { + return new OperationResult(in); + } + + public OperationResult[] newArray(int length) { + return new OperationResult[length]; + } + }; + + protected OperationResult(Parcel in) { + resultCode = in.readInt(); + token = in.readStrongBinder(); + inputConsumed = in.readInt(); + output = in.createByteArray(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel out, int flags) { + out.writeInt(resultCode); + out.writeStrongBinder(token); + out.writeInt(inputConsumed); + out.writeByteArray(output); + } +} diff --git a/core/java/android/webkit/WebMessage.java b/core/java/android/webkit/WebMessage.java new file mode 100644 index 0000000..73ee03b --- /dev/null +++ b/core/java/android/webkit/WebMessage.java @@ -0,0 +1,63 @@ +/* + * 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 android.webkit; + +/** + * The Java representation of the HTML5 PostMessage event. See + * https://html.spec.whatwg.org/multipage/comms.html#the-messageevent-interfaces + * for definition of a MessageEvent in HTML5. + * + * @hide unhide when implementation is complete + */ +public class WebMessage { + + private String mData; + private WebMessagePort[] mPorts; + + /** + * Creates a WebMessage. + * @param data the data of the message. + */ + public WebMessage(String data) { + mData = data; + } + + /** + * Creates a WebMessage. + * @param data the data of the message. + * @param ports the ports array that are sent with the message. + */ + public WebMessage(String data, WebMessagePort[] ports) { + mData = data; + mPorts = ports; + } + + /** + * Returns the data of the message. + */ + public String getData() { + return mData; + } + + /** + * Returns the ports that are sent with the message, or null if no port + * is sent. + */ + public WebMessagePort[] getPorts() { + return mPorts; + } +} diff --git a/core/java/android/webkit/WebMessagePort.java b/core/java/android/webkit/WebMessagePort.java new file mode 100644 index 0000000..f4347a5 --- /dev/null +++ b/core/java/android/webkit/WebMessagePort.java @@ -0,0 +1,87 @@ +/* + * 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 android.webkit; + +import android.os.Handler; + +/** + * The Java representation of the HTML5 Message Port. See + * https://html.spec.whatwg.org/multipage/comms.html#messageport + * for definition of MessagePort in HTML5. + * + * A Message port represents one endpoint of a Message Channel. In Android + * webview, there is no separate Message Channel object. When a message channel + * is created, both ports are tangled to each other and started, and then + * returned in a MessagePort array, see {@link WebView#createMessageChannel} + * for creating a message channel. + * + * When a message port is first created or received via transfer, it does not + * have a WebMessageListener to receive web messages. The messages are queued until + * a WebMessageListener is set. + * + * @hide unhide when implementation is complete + */ +public abstract class WebMessagePort { + + /** + * The listener for handling MessagePort events. The message listener + * methods are called on the main thread. If the embedder application + * wants to receive the messages on a different thread, it can do this + * by passing a Handler in {@link setWebMessageListener(WebMessageListener, Handler)}. + * In the latter case, the application should be extra careful for thread safety + * since WebMessagePort methods should be called on main thread. + */ + public static abstract class WebMessageListener { + /** + * Message listener for receiving onMessage events. + * + * @param port The WebMessagePort that the message is destined for + * @param message The message from the entangled port. + */ + public abstract void onMessage(WebMessagePort port, WebMessage message); + } + + /** + * Post a WebMessage to the entangled port. + * + * @param The message. + * + * @throws IllegalStateException If message port is already transferred or closed. + */ + public abstract void postMessage(WebMessage message); + + /** + * Close the message port and free any resources associated with it. + */ + public abstract void close(); + + /** + * Sets a listener to receive message events on the main thread. + * + * @param listener The message listener. + */ + public abstract void setWebMessageListener(WebMessageListener listener); + + /** + * Sets a listener to receive message events on the handler that is provided + * by the application. + * + * @param listener The message listener. + * @param handler The handler to receive the message messages. + */ + public abstract void setWebMessageListener(WebMessageListener listener, Handler handler); +} diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java index 6793634..230c498 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -27,6 +27,7 @@ import android.graphics.Picture; import android.graphics.Rect; import android.graphics.drawable.Drawable; import android.net.http.SslCertificate; +import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Looper; @@ -1788,6 +1789,35 @@ public class WebView extends AbsoluteLayout } /** + * Creates a message channel to communicate with JS and returns the message + * ports that represent the endpoints of this message channel. The HTML5 message + * channel functionality is described here: + * https://html.spec.whatwg.org/multipage/comms.html#messagechannel + * + * The returned message channels are entangled and already in started state. + * + * @return Two message ports that form the message channel. + * + * @hide unhide when implementation is complete + */ + public WebMessagePort[] createWebMessageChannel() { + checkThread(); + if (TRACE) Log.d(LOGTAG, "createWebMessageChannel"); + return mProvider.createWebMessageChannel(); + } + + /** + * Post a message to main frame. + * + * @hide unhide when implementation is complete + */ + public void postMessageToMainFrame(WebMessage message, Uri targetOrigin) { + checkThread(); + if (TRACE) Log.d(LOGTAG, "postMessageToMainFrame. TargetOrigin=" + targetOrigin); + mProvider.postMessageToMainFrame(message, targetOrigin); + } + + /** * Gets the WebSettings object used to control the settings for this * WebView. * diff --git a/core/java/android/webkit/WebViewProvider.java b/core/java/android/webkit/WebViewProvider.java index 2aee57b..2d8f1e4 100644 --- a/core/java/android/webkit/WebViewProvider.java +++ b/core/java/android/webkit/WebViewProvider.java @@ -228,6 +228,10 @@ public interface WebViewProvider { public void removeJavascriptInterface(String interfaceName); + public WebMessagePort[] createWebMessageChannel(); + + public void postMessageToMainFrame(WebMessage message, Uri targetOrigin); + public WebSettings getSettings(); public void setMapTrackballToArrowKeys(boolean setMap); diff --git a/core/java/android/widget/DatePickerCalendarDelegate.java b/core/java/android/widget/DatePickerCalendarDelegate.java index e71b383..69a2b06 100644..100755 --- a/core/java/android/widget/DatePickerCalendarDelegate.java +++ b/core/java/android/widget/DatePickerCalendarDelegate.java @@ -114,8 +114,8 @@ class DatePickerCalendarDelegate extends DatePicker.AbstractDatePickerDelegate i mTempDate = getCalendarForLocale(mMaxDate, locale); mCurrentDate = getCalendarForLocale(mCurrentDate, locale); - mMinDate.set(DEFAULT_START_YEAR, 1, 1); - mMaxDate.set(DEFAULT_END_YEAR, 12, 31); + mMinDate.set(DEFAULT_START_YEAR, Calendar.JANUARY, 1); + mMaxDate.set(DEFAULT_END_YEAR, Calendar.DECEMBER, 31); final Resources res = mDelegator.getResources(); final TypedArray a = mContext.obtainStyledAttributes(attrs, diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index c9b44be..a55fe9a 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -399,7 +399,7 @@ class ZygoteConnection { throws IllegalArgumentException { int curArg = 0; - boolean seenRuntimeArgs = true; + boolean seenRuntimeArgs = false; for ( /* curArg */ ; curArg < args.length; curArg++) { String arg = args[curArg]; @@ -533,14 +533,18 @@ class ZygoteConnection { } } - if (!seenRuntimeArgs) { - throw new IllegalArgumentException("Unexpected argument : " + args[curArg]); - } - - remainingArgs = new String[args.length - curArg]; + if (abiListQuery) { + if (args.length - curArg > 0) { + throw new IllegalArgumentException("Unexpected arguments after --query-abi-list."); + } + } else { + if (!seenRuntimeArgs) { + throw new IllegalArgumentException("Unexpected argument : " + args[curArg]); + } - System.arraycopy(args, curArg, remainingArgs, 0, - remainingArgs.length); + remainingArgs = new String[args.length - curArg]; + System.arraycopy(args, curArg, remainingArgs, 0, remainingArgs.length); + } } } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 98c2a11..98638ed 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -504,8 +504,8 @@ public class ZygoteInit { "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007", "--capabilities=" + capabilities + "," + capabilities, - "--runtime-init", "--nice-name=system_server", + "--runtime-args", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; diff --git a/core/jni/Android.mk b/core/jni/Android.mk index d070c97..20ece24 100644 --- a/core/jni/Android.mk +++ b/core/jni/Android.mk @@ -5,7 +5,7 @@ LOCAL_ADDITIONAL_DEPENDENCIES := $(LOCAL_PATH)/Android.mk LOCAL_CFLAGS += -DHAVE_CONFIG_H -DKHTML_NO_EXCEPTIONS -DGKWQ_NO_JAVA LOCAL_CFLAGS += -DNO_SUPPORT_JS_BINDING -DQT_NO_WHEELEVENT -DKHTML_NO_XBL LOCAL_CFLAGS += -U__APPLE__ -LOCAL_CFLAGS += -Wno-unused-parameter -Wno-int-to-pointer-cast +LOCAL_CFLAGS += -Wno-unused-parameter LOCAL_CFLAGS += -Wno-non-virtual-dtor LOCAL_CFLAGS += -Wno-maybe-uninitialized -Wno-parentheses LOCAL_CPPFLAGS += -Wno-conversion-null diff --git a/core/jni/android_opengl_EGL14.cpp b/core/jni/android_opengl_EGL14.cpp index 1afcf73..36f7963 100644 --- a/core/jni/android_opengl_EGL14.cpp +++ b/core/jni/android_opengl_EGL14.cpp @@ -160,7 +160,8 @@ static jobject android_eglGetDisplayInt (JNIEnv *_env, jobject _this, jint display_id) { - if ((EGLNativeDisplayType)display_id != EGL_DEFAULT_DISPLAY) { + if (static_cast<uintptr_t>(display_id) != + reinterpret_cast<uintptr_t>(EGL_DEFAULT_DISPLAY)) { jniThrowException(_env, "java/lang/UnsupportedOperationException", "eglGetDisplay"); return 0; } diff --git a/core/jni/android_opengl_GLES30.cpp b/core/jni/android_opengl_GLES30.cpp index 713fff9..226162d 100644 --- a/core/jni/android_opengl_GLES30.cpp +++ b/core/jni/android_opengl_GLES30.cpp @@ -1935,7 +1935,11 @@ android_glGetTransformFeedbackVarying__IIILjava_nio_IntBuffer_2Ljava_nio_IntBuff (GLsizei *)length, (GLint *)size, (GLenum *)type, - (char *)name + // The cast below is incorrect. The driver will end up writing to the + // address specified by name, which will always crash the process since + // it is guaranteed to be in low memory. The additional static_cast + // suppresses the warning for now. http://b/19478262 + (char *)static_cast<uintptr_t>(name) ); if (_typeArray) { releasePointer(_env, _typeArray, type, JNI_TRUE); @@ -3643,7 +3647,7 @@ android_glDrawElementsInstanced__IIIII (GLenum)mode, (GLsizei)count, (GLenum)type, - (GLvoid *)indicesOffset, + (GLvoid *)static_cast<uintptr_t>(indicesOffset), (GLsizei)instanceCount ); } diff --git a/core/jni/android_util_EventLog.cpp b/core/jni/android_util_EventLog.cpp index 2df13b7..5cb8b2e 100644 --- a/core/jni/android_util_EventLog.cpp +++ b/core/jni/android_util_EventLog.cpp @@ -159,7 +159,7 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz UNUSED, } struct logger_list *logger_list = android_logger_list_open( - LOG_ID_EVENTS, O_RDONLY | O_NONBLOCK, 0, 0); + LOG_ID_EVENTS, ANDROID_LOG_RDONLY | ANDROID_LOG_NONBLOCK, 0, 0); if (!logger_list) { jniThrowIOException(env, errno); @@ -188,6 +188,10 @@ static void android_util_EventLog_readEvents(JNIEnv* env, jobject clazz UNUSED, break; } + if (log_msg.id() != LOG_ID_EVENTS) { + continue; + } + int32_t tag = * (int32_t *) log_msg.msg(); int found = 0; diff --git a/core/res/res/values-mcc259-mnc05/config.xml b/core/res/res/values-mcc259-mnc05/config.xml new file mode 100644 index 0000000..065668c --- /dev/null +++ b/core/res/res/values-mcc259-mnc05/config.xml @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- The list of ril radio technologies (see ServiceState.java) which only support + a single data connection at one time. This may change by carrier via + overlays (some don't support multiple pdp on UMTS). All unlisted radio + tech types support unlimited types (practically only 2-4 used). --> + <integer-array name="config_onlySingleDcAllowed"> + <item>1</item> <!-- GPRS --> + <item>2</item> <!-- EDGE --> + <item>3</item> <!-- UMTS --> + <item>9</item> <!-- HSDPA --> + <item>10</item> <!-- HSUPA --> + <item>11</item> <!-- HSPA --> + <item>14</item> <!-- LTE --> + <item>15</item> <!-- HSPAP --> + </integer-array> +</resources> diff --git a/graphics/java/android/graphics/Color.java b/graphics/java/android/graphics/Color.java index 8fbedae..3fe5672 100644 --- a/graphics/java/android/graphics/Color.java +++ b/graphics/java/android/graphics/Color.java @@ -200,10 +200,11 @@ public class Color { * exception. Supported formats are: * #RRGGBB * #AARRGGBB + * or one of the following names: * 'red', 'blue', 'green', 'black', 'white', 'gray', 'cyan', 'magenta', * 'yellow', 'lightgray', 'darkgray', 'grey', 'lightgrey', 'darkgrey', - * 'aqua', 'fuschia', 'lime', 'maroon', 'navy', 'olive', 'purple', - * 'silver', 'teal' + * 'aqua', 'fuchsia', 'lime', 'maroon', 'navy', 'olive', 'purple', + * 'silver', 'teal'. */ public static int parseColor(String colorString) { if (colorString.charAt(0) == '#') { diff --git a/keystore/java/android/security/KeyStore.java b/keystore/java/android/security/KeyStore.java index e753a7c..bfbf028 100644 --- a/keystore/java/android/security/KeyStore.java +++ b/keystore/java/android/security/KeyStore.java @@ -18,8 +18,14 @@ package android.security; import com.android.org.conscrypt.NativeCrypto; +import android.os.Binder; +import android.os.IBinder; import android.os.RemoteException; import android.os.ServiceManager; +import android.security.keymaster.ExportResult; +import android.security.keymaster.KeyCharacteristics; +import android.security.keymaster.KeymasterArguments; +import android.security.keymaster.OperationResult; import android.util.Log; import java.util.Locale; @@ -58,6 +64,8 @@ public class KeyStore { private final IKeystoreService mBinder; + private IBinder mToken; + private KeyStore(IKeystoreService binder) { mBinder = binder; } @@ -68,6 +76,13 @@ public class KeyStore { return new KeyStore(keystore); } + private synchronized IBinder getToken() { + if (mToken == null) { + mToken = new Binder(); + } + return mToken; + } + static int getKeyTypeForAlgorithm(String keyType) { if ("RSA".equalsIgnoreCase(keyType)) { return NativeCrypto.EVP_PKEY_RSA; @@ -363,4 +378,100 @@ public class KeyStore { public int getLastError() { return mError; } + + public boolean addRngEntropy(byte[] data) { + try { + return mBinder.addRngEntropy(data) == NO_ERROR; + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return false; + } + } + + public int generateKey(String alias, KeymasterArguments args, int uid, int flags, + KeyCharacteristics outCharacteristics) { + try { + return mBinder.generateKey(alias, args, uid, flags, outCharacteristics); + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return SYSTEM_ERROR; + } + } + + public int generateKey(String alias, KeymasterArguments args, int flags, + KeyCharacteristics outCharacteristics) { + return generateKey(alias, args, UID_SELF, flags, outCharacteristics); + } + + public int getKeyCharacteristics(String alias, byte[] clientId, byte[] appId, + KeyCharacteristics outCharacteristics) { + try { + return mBinder.getKeyCharacteristics(alias, clientId, appId, outCharacteristics); + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return SYSTEM_ERROR; + } + } + + public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData, + int uid, int flags, KeyCharacteristics outCharacteristics) { + try { + return mBinder.importKey(alias, args, format, keyData, uid, flags, + outCharacteristics); + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return SYSTEM_ERROR; + } + } + + public int importKey(String alias, KeymasterArguments args, int format, byte[] keyData, + int flags, KeyCharacteristics outCharacteristics) { + return importKey(alias, args, format, keyData, UID_SELF, flags, outCharacteristics); + } + + public ExportResult exportKey(String alias, int format, byte[] clientId, byte[] appId) { + try { + return mBinder.exportKey(alias, format, clientId, appId); + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return null; + } + } + + public OperationResult begin(String alias, int purpose, boolean pruneable, + KeymasterArguments args, KeymasterArguments outArgs) { + try { + return mBinder.begin(getToken(), alias, purpose, pruneable, args, outArgs); + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return null; + } + } + + public OperationResult update(IBinder token, KeymasterArguments arguments, byte[] input) { + try { + return mBinder.update(token, arguments, input); + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return null; + } + } + + public OperationResult finish(IBinder token, KeymasterArguments arguments, byte[] signature) { + try { + return mBinder.finish(token, arguments, signature); + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return null; + } + } + + public int abort(IBinder token) { + try { + return mBinder.abort(token); + } catch (RemoteException e) { + Log.w(TAG, "Cannot connect to keystore", e); + return SYSTEM_ERROR; + } + } } diff --git a/libs/androidfw/Asset.cpp b/libs/androidfw/Asset.cpp index 4b3382e..782806e 100644 --- a/libs/androidfw/Asset.cpp +++ b/libs/androidfw/Asset.cpp @@ -532,7 +532,7 @@ off64_t _FileAsset::seek(off64_t offset, int whence) void _FileAsset::close(void) { if (mMap != NULL) { - mMap->release(); + delete mMap; mMap = NULL; } if (mBuf != NULL) { @@ -612,7 +612,7 @@ const void* _FileAsset::getBuffer(bool wordAligned) map = new FileMap; if (!map->create(NULL, fileno(mFp), mStart, mLength, true)) { - map->release(); + delete map; return NULL; } @@ -827,7 +827,7 @@ off64_t _CompressedAsset::seek(off64_t offset, int whence) void _CompressedAsset::close(void) { if (mMap != NULL) { - mMap->release(); + delete mMap; mMap = NULL; } diff --git a/libs/androidfw/ZipFileRO.cpp b/libs/androidfw/ZipFileRO.cpp index ef0d072..af3d9b3 100644 --- a/libs/androidfw/ZipFileRO.cpp +++ b/libs/androidfw/ZipFileRO.cpp @@ -200,7 +200,7 @@ FileMap* ZipFileRO::createEntryFileMap(ZipEntryRO entry) const FileMap* newMap = new FileMap(); if (!newMap->create(mFileName, fd, ze.offset, actualLen, true)) { - newMap->release(); + delete newMap; return NULL; } diff --git a/rs/java/android/renderscript/RenderScript.java b/rs/java/android/renderscript/RenderScript.java index 5e150e9..417bfe2 100644 --- a/rs/java/android/renderscript/RenderScript.java +++ b/rs/java/android/renderscript/RenderScript.java @@ -887,8 +887,59 @@ public class RenderScript { return rsnPathCreate(mContext, prim, isStatic, vtx, loop, q); } + native void rsnScriptIntrinsicBLAS_Single(long con, 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); + 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) { + validate(); + rsnScriptIntrinsicBLAS_Single(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU); + } + + native void rsnScriptIntrinsicBLAS_Double(long con, 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); + 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) { + validate(); + rsnScriptIntrinsicBLAS_Double(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alpha, A, B, beta, C, incX, incY, KL, KU); + } + + native void rsnScriptIntrinsicBLAS_Complex(long con, 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); + 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) { + validate(); + rsnScriptIntrinsicBLAS_Complex(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU); + } + + native void rsnScriptIntrinsicBLAS_Z(long con, 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); + 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) { + validate(); + rsnScriptIntrinsicBLAS_Z(mContext, id, func, TransA, TransB, Side, Uplo, Diag, M, N, K, alphaX, alphaY, A, B, betaX, betaY, C, incX, incY, KL, KU); + } + + long mDev; long mContext; + private boolean mDestroyed = false; + @SuppressWarnings({"FieldCanBeLocal"}) MessageThread mMessageThread; @@ -1333,6 +1384,38 @@ public class RenderScript { nContextFinish(); } + private void helpDestroy() { + boolean shouldDestroy = false; + synchronized(this) { + if (!mDestroyed) { + shouldDestroy = true; + mDestroyed = true; + } + } + + if (shouldDestroy) { + nContextFinish(); + + nContextDeinitToClient(mContext); + mMessageThread.mRun = false; + try { + mMessageThread.join(); + } catch(InterruptedException e) { + } + + nContextDestroy(); + + nDeviceDestroy(mDev); + mDev = 0; + } + } + + 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 @@ -1341,19 +1424,7 @@ public class RenderScript { */ public void destroy() { validate(); - nContextFinish(); - - nContextDeinitToClient(mContext); - mMessageThread.mRun = false; - try { - mMessageThread.join(); - } catch(InterruptedException e) { - } - - nContextDestroy(); - - nDeviceDestroy(mDev); - mDev = 0; + helpDestroy(); } boolean isAlive() { diff --git a/rs/java/android/renderscript/ScriptIntrinsicBLAS.java b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java new file mode 100644 index 0000000..90d2300 --- /dev/null +++ b/rs/java/android/renderscript/ScriptIntrinsicBLAS.java @@ -0,0 +1,1489 @@ +/* + * 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 android.renderscript; + +import android.annotation.IntDef; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +/** + * + * BLAS + * + * @hide + **/ +public final class ScriptIntrinsicBLAS extends ScriptIntrinsic { + private Allocation mLUT; + + 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; + + /** + */ + public static ScriptIntrinsicBLAS create(RenderScript rs) { + long id = rs.nScriptIntrinsicCreate(13, Element.U32(rs).getID(rs)); + return new ScriptIntrinsicBLAS(id, rs); + } + + @IntDef({NO_TRANSPOSE, TRANSPOSE, CONJ_TRANSPOSE}) + @Retention(RetentionPolicy.SOURCE) + public @interface Transpose {} + + @IntDef({UPPER, LOWER}) + @Retention(RetentionPolicy.SOURCE) + public @interface Uplo {} + + @IntDef({NON_UNIT, UNIT}) + @Retention(RetentionPolicy.SOURCE) + public @interface Diag {} + + @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 != LEFT && Uplo != RIGHT) { + 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().getY() != expectedXDim) { + throw new RSRuntimeException("Incorrect vector dimensions for GEMV"); + } + } + 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(); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0); + } + 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(); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0); + } + 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(); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0); + } + 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(); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0); + } + + 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(); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, KL, KU); + } + 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(); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, KL, KU); + } + 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(); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, KL, KU); + } + 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(); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgbmv, TransA, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, KL, KU); + } + + static void validateTRMV(Element e, @Transpose int TransA, Allocation A, Allocation X, int incX) { + validateTranspose(TransA); + 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); + if (Ap.getType().getX() != ((N * (N+1)) / 2)) { + throw new RSRuntimeException("Invalid dimension for Ap"); + } + + int expectedXDim = 1 + (N - 1) * incX; + if (X.getType().getX() != expectedXDim) { + throw new RSRuntimeException("Incorrect vector dimensions for SYMV"); + } + + return N; + } + + void STRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) { + validateTRMV(Element.F32(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + void DTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) { + validateTRMV(Element.F64(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + void CTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) { + validateTRMV(Element.F32_2(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + void ZTRMV(@Uplo int Uplo, @Transpose int TransA, @Diag int Diag, Allocation A, Allocation X, int incX) { + validateTRMV(Element.F64_2(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + 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 + validateTRMV(Element.F32(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + 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 + validateTRMV(Element.F64(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + 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 + validateTRMV(Element.F32_2(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + 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 + validateTRMV(Element.F64_2(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbmv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpmv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + 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), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + + } + 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), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + + } + 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), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + + } + 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), TransA, A, X, incX); + int N = A.getType().getY(); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztrsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + + } + 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 + validateTRMV(Element.F32(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + if (K < 0) { + throw new RSRuntimeException("Number of diagonals must be positive"); + } + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + 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 + validateTRMV(Element.F64(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + if (K < 0) { + throw new RSRuntimeException("Number of diagonals must be positive"); + } + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, A.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + 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 + validateTRMV(Element.F32_2(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + if (K < 0) { + throw new RSRuntimeException("Number of diagonals must be positive"); + } + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + 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 + validateTRMV(Element.F64_2(mRS), TransA, A, X, incX); + int N = A.getType().getY(); + if (K < 0) { + throw new RSRuntimeException("Number of diagonals must be positive"); + } + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztbsv, TransA, 0, 0, Uplo, Diag, 0, N, K, 0, 0, A.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_stpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dtpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ctpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ztpsv, TransA, 0, 0, Uplo, Diag, 0, N, 0, 0, 0, Ap.getID(mRS), X.getID(mRS), 0, 0, 0, incX, 0, 0, 0); + } + + /** + * 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"); + } + + 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"); + } + + int expectedXDim = 1 + (N - 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"); + } + + 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"); + } + + int expectedXDim = 1 + (N - 1) * incX; + if (X.getType().getX() != expectedXDim) { + throw new RSRuntimeException("Incorrect vector dimensions for SPMV"); + } + + 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"); + } + + 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"); + } + + 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 SPMV"); + } + + return N; + } + + 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); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0); + } + 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 + int N = validateSYMV(Element.F32(mRS), Uplo, A, X, Y, incX, incY); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, Ap.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0); + } + void SGER(float alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) { + int M = A.getType().getY(); + int N = A.getType().getX(); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sger, 0, 0, 0, 0, 0, M, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0.f, A.getID(mRS), incX, incY, 0, 0); + } + void SSYR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) { + int N = validateSYR(Element.F32(mRS), Uplo, X, incX, A); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), A.getID(mRS), 0.f, 0, incX, 0, 0, 0); + } + void SSPR(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation Ap) { + int N = validateSPR(Element.F32(mRS), Uplo, X, incX, Ap); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Ap.getID(mRS), 0.f, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, A.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, Ap.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0); + } + 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 + int N = validateSYMV(Element.F64(mRS), Uplo, A, X, Y, incX, incY); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha, A.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, Ap.getID(mRS), X.getID(mRS), beta, Y.getID(mRS), incX, incY, 0, 0); + } + void DGER(double alpha, Allocation X, int incX, Allocation Y, int incY, Allocation A) { + int M = A.getType().getY(); + int N = A.getType().getX(); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dger, 0, 0, 0, 0, 0, M, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0.f, A.getID(mRS), incX, incY, 0, 0); + } + void DSYR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) { + int N = validateSYR(Element.F64(mRS), Uplo, X, incX, A); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), A.getID(mRS), 0.f, 0, incX, 0, 0, 0); + } + void DSPR(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation Ap) { + int N = validateSPR(Element.F64(mRS), Uplo, X, incX, Ap); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Ap.getID(mRS), 0.f, 0, incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, A.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dspr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, X.getID(mRS), Y.getID(mRS), 0, Ap.getID(mRS), incX, incY, 0, 0); + } + + + /** + * 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(); + + int expectedXDim = 1 + (N - 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"); + } + + } + + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0); + } + 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"); + } + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, Ap.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0); + } + 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(); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0); + } + 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(); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0); + } + void CHER(@Uplo int Uplo, float alpha, Allocation X, int incX, Allocation A) { + // same as SYR + int N = validateSYR(Element.F32(mRS), Uplo, X, incX, A); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, A.getID(mRS), incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, Ap.getID(mRS), incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, Ap.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0); + } + 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"); + } + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhbmv, 0, 0, 0, Uplo, 0, 0, N, K, alpha.x, alpha.y, A.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpmv, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, Ap.getID(mRS), X.getID(mRS), beta.x, beta.y, Y.getID(mRS), incX, incY, 0, 0); + } + 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(); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgeru, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0); + } + 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(); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgerc, 0, 0, 0, 0, 0, M, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0); + } + void ZHER(@Uplo int Uplo, double alpha, Allocation X, int incX, Allocation A) { + // same as SYR + int N = validateSYR(Element.F64(mRS), Uplo, X, incX, A); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, A.getID(mRS), incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr, 0, 0, 0, Uplo, 0, 0, N, 0, alpha, 0, X.getID(mRS), 0, 0, 0, Ap.getID(mRS), incX, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, A.getID(mRS), incX, incY, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhpr2, 0, 0, 0, Uplo, 0, 0, N, 0, alpha.x, alpha.y, X.getID(mRS), Y.getID(mRS), 0, 0, Ap.getID(mRS), incX, incY, 0, 0); + } + + + /** + * Level 3 BLAS + */ + + static void validateL3(Element e, int TransA, int TransB, int Side, Allocation A, Allocation B, Allocation C) { + int aX = -1, aY = -1, bX = -1, bY = -1, cX = -1, cY = -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) { + cX = C.getType().getY(); + cY = C.getType().getX(); + } + if (Side == RIGHT) { + if (B != null) { + bX = A.getType().getY(); + bY = A.getType().getX(); + } + if (A != null) { + aX = B.getType().getY(); + aY = B.getType().getX(); + } + } else { + if (A != null) { + if (TransA == TRANSPOSE) { + aY = A.getType().getY(); + aX = A.getType().getX(); + } else { + aX = A.getType().getY(); + aY = A.getType().getX(); + } + } + if (B != null) { + if (TransB == TRANSPOSE) { + bY = B.getType().getY(); + bX = B.getType().getX(); + } else { + bX = B.getType().getY(); + bY = B.getType().getX(); + } + } + } + if (A != null && B != null && C != null) { + if (aY != bX || aX != cX || bY != cY) { + throw new RSRuntimeException("Called BLAS with invalid dimensions"); + } + } else if (A != null && C != null) { + // A and C only + if (aX != cY || aY != cX) { + throw new RSRuntimeException("Called BLAS with invalid dimensions"); + } + } else if (A != null && B != null) { + // A and B only + } + + } + + 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 == TRANSPOSE) { + M = A.getType().getX(); + K = A.getType().getY(); + } else { + M = A.getType().getY(); + K = A.getType().getX(); + } + if (TransB == TRANSPOSE) { + N = B.getType().getY(); + } else { + N = B.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_sgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha, A.getID(mRS), B.getID(mRS), + beta, C.getID(mRS), 0, 0, 0, 0); + } + 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 == TRANSPOSE) { + M = A.getType().getX(); + K = A.getType().getY(); + } else { + M = A.getType().getY(); + K = A.getType().getX(); + } + if (TransB == TRANSPOSE) { + N = B.getType().getY(); + } else { + N = B.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha, A.getID(mRS), B.getID(mRS), + beta, C.getID(mRS), 0, 0, 0, 0); + } + 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 == TRANSPOSE) { + M = A.getType().getX(); + K = A.getType().getY(); + } else { + M = A.getType().getY(); + K = A.getType().getX(); + } + if (TransB == TRANSPOSE) { + N = B.getType().getY(); + } else { + N = B.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), + beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0); + } + + 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 == TRANSPOSE) { + M = A.getType().getX(); + K = A.getType().getY(); + } else { + M = A.getType().getY(); + K = A.getType().getX(); + } + if (TransB == TRANSPOSE) { + N = B.getType().getY(); + } else { + N = B.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zgemm, TransA, TransB, 0, 0, 0, M, N, K, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), + beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0); + } + + public void SSYMM(@Side int Side, @Uplo int Uplo, float alpha, Allocation A, + Allocation B, float beta, Allocation C) { + validateSide(Side); + validateUplo(Uplo); + validateL3(Element.F32(mRS), 0, 0, Side, A, B, C); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, A.getID(mRS), B.getID(mRS), + beta, C.getID(mRS), 0, 0, 0, 0); + } + public void DSYMM(@Side int Side, @Uplo int Uplo, double alpha, Allocation A, + Allocation B, double beta, Allocation C) { + validateSide(Side); + validateUplo(Uplo); + validateL3(Element.F64(mRS), 0, 0, Side, A, B, C); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha, A.getID(mRS), B.getID(mRS), + beta, C.getID(mRS), 0, 0, 0, 0); + } + public void CSYMM(@Side int Side, @Uplo int Uplo, Float2 alpha, Allocation A, + Allocation B, Float2 beta, Allocation C) { + validateSide(Side); + validateUplo(Uplo); + validateL3(Element.F32_2(mRS), 0, 0, Side, A, B, C); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), + beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0); + } + public void ZSYMM(@Side int Side, @Uplo int Uplo, Double2 alpha, Allocation A, + Allocation B, Double2 beta, Allocation C) { + validateSide(Side); + validateUplo(Uplo); + validateL3(Element.F64_2(mRS), 0, 0, Side, A, B, C); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsymm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), + beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0); + } + + 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 == TRANSPOSE) { + K = A.getType().getY(); + } else { + K = A.getType().getX(); + } + + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), 0, beta, C.getID(mRS), 0, 0, 0, 0); + } + + 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 == TRANSPOSE) { + K = A.getType().getY(); + } else { + K = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_dsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), 0, beta, C.getID(mRS), 0, 0, 0, 0); + } + public void CSYRK(@Uplo int Uplo, @Transpose int Trans, float alphaX, float alphaY, Allocation A, float betaX, float betaY, Allocation C) { + validateTranspose(Trans); + validateUplo(Uplo); + validateL3(Element.F32_2(mRS), Trans, 0, 0, A, null, C); + int K = -1; + if (Trans == TRANSPOSE) { + K = A.getType().getY(); + } else { + K = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_csyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alphaX, alphaY, A.getID(mRS), 0, betaX, betaY, + C.getID(mRS), 0, 0, 0, 0); + } + public void ZSYRK(@Uplo int Uplo, @Transpose int Trans, double alphaX, double alphaY, Allocation A, double betaX, double betaY, Allocation C) { + validateTranspose(Trans); + validateUplo(Uplo); + validateL3(Element.F64_2(mRS), Trans, 0, 0, A, null, C); + int K = -1; + if (Trans == TRANSPOSE) { + K = A.getType().getY(); + } else { + K = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zsyrk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alphaX, alphaY, A.getID(mRS), 0, betaX, betaY, + C.getID(mRS), 0, 0, 0, 0); + } + + 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"); + } + } + 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 == TRANSPOSE) { + K = A.getType().getY(); + } else { + K = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_ssyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), B.getID(mRS), beta, C.getID(mRS), 0, 0, 0, 0); + } + 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 == TRANSPOSE) { + K = A.getType().getY(); + } else { + K = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_ssyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha, A.getID(mRS), B.getID(mRS), beta, C.getID(mRS), 0, 0, 0, 0); + } + 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 == TRANSPOSE) { + K = A.getType().getY(); + } else { + K = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_ssyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0); + } + 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 == TRANSPOSE) { + K = A.getType().getY(); + } else { + K = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_ssyr2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), K, alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), beta.x, beta.y, C.getID(mRS), 0, 0, 0, 0); + } + + static void validateTRMM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) { + validateSide(Side); + validateTranspose(TransA); + int aX = -1, aY = -1, bX = -1, bY = -1; + if (!A.getType().getElement().isCompatible(e) || + !B.getType().getElement().isCompatible(e)) { + throw new RSRuntimeException("Called BLAS with wrong Element type"); + } + if (TransA == TRANSPOSE) { + aY = A.getType().getY(); + aX = A.getType().getX(); + } else { + aY = A.getType().getX(); + aX = A.getType().getY(); + } + bX = B.getType().getY(); + bY = B.getType().getX(); + if (Side == LEFT) { + if (aX == 0 || aY != bX) { + throw new RSRuntimeException("Called TRMM with invalid matrices"); + } + } else { + if (bY != aX || aY == 0) { + throw new RSRuntimeException("Called TRMM with invalid matrices"); + } + } + } + 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); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0, + alpha, A.getID(mRS), B.getID(mRS), 0.f, 0, 0, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_strmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0, + alpha, A.getID(mRS), B.getID(mRS), 0.f, 0, 0, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_strmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0, + alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_strmm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0, + alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0, 0); + } + + static void validateTRSM(Element e, @Side int Side, @Transpose int TransA, Allocation A, Allocation B) { + int adim = -1, bX = -1, bY = -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"); + } + bX = B.getType().getY(); + bY = B.getType().getX(); + if (Side == LEFT) { + // A is M*M + if (adim != bY) { + throw new RSRuntimeException("Called TRSM with invalid matrix dimensions"); + } + } else { + // A is N*N + if (adim != bX) { + throw new RSRuntimeException("Called TRSM with invalid matrix dimensions"); + } + } + } + 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); + mRS.nScriptIntrinsicBLAS_Single(getID(mRS), RsBlas_strsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0, + alpha, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Double(getID(mRS), RsBlas_strsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0, + alpha, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_strsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0, + alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0, 0); + } + 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); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_strsm, TransA, 0, Side, Uplo, Diag, B.getType().getY(), B.getType().getX(), 0, + alpha.x, alpha.y, A.getID(mRS), B.getID(mRS), 0, 0, 0, 0, 0, 0, 0); + } + + 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"); + } + } + public void CHEMM(@Side int Side, @Uplo int Uplo, float alpha, Allocation A, Allocation B, float beta, Allocation C) { + validateUplo(Uplo); + validateHEMM(Element.F32_2(mRS), Side, A, B, C); + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_chemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, + alpha, 0, A.getID(mRS), B.getID(mRS), beta, 0, C.getID(mRS), 0, 0, 0, 0); + } + public void ZHEMM(@Side int Side, @Uplo int Uplo, double alpha, Allocation A, Allocation B, double beta, Allocation C) { + validateUplo(Uplo); + validateHEMM(Element.F32_2(mRS), Side, A, B, C); + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zhemm, 0, 0, Side, Uplo, 0, C.getType().getY(), C.getType().getX(), 0, + alpha, 0, A.getID(mRS), B.getID(mRS), beta, 0, C.getID(mRS), 0, 0, 0, 0); + } + + 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().getX()) { + throw new RSRuntimeException("Called HERK with invalid A"); + } + } else { + if (cdim != A.getType().getY()) { + throw new RSRuntimeException("Called HERK with invalid A"); + } + } + } + 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 == TRANSPOSE) { + k = A.getType().getY(); + } else { + k = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, + alpha, 0, A.getID(mRS), 0, beta, 0, C.getID(mRS), 0, 0, 0, 0); + } + 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 == TRANSPOSE) { + k = A.getType().getY(); + } else { + k = A.getType().getX(); + } + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zherk, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, + alpha, 0, A.getID(mRS), 0, beta, 0, C.getID(mRS), 0, 0, 0, 0); + } + + 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"); + } + } + 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(); + } + mRS.nScriptIntrinsicBLAS_Complex(getID(mRS), RsBlas_cher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y, + A.getID(mRS), B.getID(mRS), beta, 0, C.getID(mRS), 0, 0, 0, 0); + } + 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(); + } + mRS.nScriptIntrinsicBLAS_Z(getID(mRS), RsBlas_zher2k, Trans, 0, 0, Uplo, 0, 0, C.getType().getX(), k, alpha.x, alpha.y, + A.getID(mRS), B.getID(mRS), beta, 0, C.getID(mRS), 0, 0, 0, 0); + } + + + +} diff --git a/rs/jni/android_renderscript_RenderScript.cpp b/rs/jni/android_renderscript_RenderScript.cpp index 198cabe..2612323 100644 --- a/rs/jni/android_renderscript_RenderScript.cpp +++ b/rs/jni/android_renderscript_RenderScript.cpp @@ -310,6 +310,143 @@ nScriptGroup2Execute(JNIEnv *_env, jobject _this, jlong con, jlong groupID) { } static void +nScriptIntrinsicBLAS_Single(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA, + jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K, + jfloat alpha, jlong A, jlong B, jfloat beta, jlong C, jint incX, jint incY, + jint KL, jint KU) { + RsBlasCall call; + memset(&call, 0, sizeof(call)); + call.func = (RsBlasFunction)func; + call.transA = (RsBlasTranspose)TransA; + call.transB = (RsBlasTranspose)TransB; + call.side = (RsBlasSide)Side; + call.uplo = (RsBlasUplo)Uplo; + call.diag = (RsBlasDiag)Diag; + call.M = M; + call.N = N; + call.K = K; + call.alpha.f = alpha; + call.beta.f = beta; + call.incX = incX; + call.incY = incY; + call.KL = KL; + call.KU = KU; + + RsAllocation in_allocs[3]; + in_allocs[0] = (RsAllocation)A; + in_allocs[1] = (RsAllocation)B; + in_allocs[2] = (RsAllocation)C; + + rsScriptForEachMulti((RsContext)con, (RsScript)id, 0, + in_allocs, sizeof(in_allocs), nullptr, + &call, sizeof(call), nullptr, 0); +} + +static void +nScriptIntrinsicBLAS_Double(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA, + jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K, + jdouble alpha, jlong A, jlong B, jdouble beta, jlong C, jint incX, jint incY, + jint KL, jint KU) { + RsBlasCall call; + memset(&call, 0, sizeof(call)); + call.func = (RsBlasFunction)func; + call.transA = (RsBlasTranspose)TransA; + call.transB = (RsBlasTranspose)TransB; + call.side = (RsBlasSide)Side; + call.uplo = (RsBlasUplo)Uplo; + call.diag = (RsBlasDiag)Diag; + call.M = M; + call.N = N; + call.K = K; + call.alpha.d = alpha; + call.beta.d = beta; + call.incX = incX; + call.incY = incY; + call.KL = KL; + call.KU = KU; + + RsAllocation in_allocs[3]; + in_allocs[0] = (RsAllocation)A; + in_allocs[1] = (RsAllocation)B; + in_allocs[2] = (RsAllocation)C; + + rsScriptForEachMulti((RsContext)con, (RsScript)id, 0, + in_allocs, sizeof(in_allocs), nullptr, + &call, sizeof(call), nullptr, 0); +} + +static void +nScriptIntrinsicBLAS_Complex(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA, + jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K, + jfloat alphaX, jfloat alphaY, jlong A, jlong B, jfloat betaX, + jfloat betaY, jlong C, jint incX, jint incY, jint KL, jint KU) { + RsBlasCall call; + memset(&call, 0, sizeof(call)); + call.func = (RsBlasFunction)func; + call.transA = (RsBlasTranspose)TransA; + call.transB = (RsBlasTranspose)TransB; + call.side = (RsBlasSide)Side; + call.uplo = (RsBlasUplo)Uplo; + call.diag = (RsBlasDiag)Diag; + call.M = M; + call.N = N; + call.K = K; + call.alpha.c.r = alphaX; + call.alpha.c.i = alphaY; + call.beta.c.r = betaX; + call.beta.c.r = betaY; + call.incX = incX; + call.incY = incY; + call.KL = KL; + call.KU = KU; + + RsAllocation in_allocs[3]; + in_allocs[0] = (RsAllocation)A; + in_allocs[1] = (RsAllocation)B; + in_allocs[2] = (RsAllocation)C; + + rsScriptForEachMulti((RsContext)con, (RsScript)id, 0, + in_allocs, sizeof(in_allocs), nullptr, + &call, sizeof(call), nullptr, 0); +} + +static void +nScriptIntrinsicBLAS_Z(JNIEnv *_env, jobject _this, jlong con, jlong id, jint func, jint TransA, + jint TransB, jint Side, jint Uplo, jint Diag, jint M, jint N, jint K, + jdouble alphaX, jdouble alphaY, jlong A, jlong B, jdouble betaX, + jdouble betaY, jlong C, jint incX, jint incY, jint KL, jint KU) { + RsBlasCall call; + memset(&call, 0, sizeof(call)); + call.func = (RsBlasFunction)func; + call.transA = (RsBlasTranspose)TransA; + call.transB = (RsBlasTranspose)TransB; + call.side = (RsBlasSide)Side; + call.uplo = (RsBlasUplo)Uplo; + call.diag = (RsBlasDiag)Diag; + call.M = M; + call.N = N; + call.K = K; + call.alpha.z.r = alphaX; + call.alpha.z.i = alphaY; + call.beta.z.r = betaX; + call.beta.z.r = betaY; + call.incX = incX; + call.incY = incY; + call.KL = KL; + call.KU = KU; + + RsAllocation in_allocs[3]; + in_allocs[0] = (RsAllocation)A; + in_allocs[1] = (RsAllocation)B; + in_allocs[2] = (RsAllocation)C; + + rsScriptForEachMulti((RsContext)con, (RsScript)id, 0, + in_allocs, sizeof(in_allocs), nullptr, + &call, sizeof(call), nullptr, 0); +} + + +static void nAssignName(JNIEnv *_env, jobject _this, jlong con, jlong obj, jbyteArray str) { if (kLogApi) { @@ -2094,6 +2231,11 @@ static JNINativeMethod methods[] = { {"rsnScriptGroupExecute", "(JJ)V", (void*)nScriptGroupExecute }, {"rsnScriptGroup2Execute", "(JJ)V", (void*)nScriptGroup2Execute }, +{"rsnScriptIntrinsicBLAS_Single", "(JJIIIIIIIIIFJJFJIIII)V", (void*)nScriptIntrinsicBLAS_Single }, +{"rsnScriptIntrinsicBLAS_Double", "(JJIIIIIIIIIDJJDJIIII)V", (void*)nScriptIntrinsicBLAS_Double }, +{"rsnScriptIntrinsicBLAS_Complex", "(JJIIIIIIIIIFFJJFFJIIII)V", (void*)nScriptIntrinsicBLAS_Complex }, +{"rsnScriptIntrinsicBLAS_Z", "(JJIIIIIIIIIDDJJDDJIIII)V", (void*)nScriptIntrinsicBLAS_Z }, + {"rsnProgramStoreCreate", "(JZZZZZZIII)J", (void*)nProgramStoreCreate }, {"rsnProgramBindConstants", "(JJIJ)V", (void*)nProgramBindConstants }, |