* vulkan: support non-contig unary/glu ops Change unary/glu ops to pass in all strides and use fastdiv for the index calculation. Put all unary ops in one file, similar to glu, to share the code. codex went ahead and added expm1 without me asking, but I had to make it do a real precision analysis rather than just making stuff up. unary.comp initially couldn't use generic_unary_head because there wasn't space for xielu's additional constants. Fixing this required packing the fastdiv 'L' values. * attempt to workaround compiler bug * resolve conflict from #23991 * use expm1
43 lines
1.3 KiB
Plaintext
43 lines
1.3 KiB
Plaintext
#version 450
|
|
|
|
#include "types.glsl"
|
|
#include "generic_unary_head.glsl"
|
|
|
|
#define GGML_TRI_TYPE_UPPER_DIAG 0
|
|
#define GGML_TRI_TYPE_UPPER 1
|
|
#define GGML_TRI_TYPE_LOWER_DIAG 2
|
|
#define GGML_TRI_TYPE_LOWER 3
|
|
|
|
layout(local_size_x = 512, local_size_y = 1, local_size_z = 1) in;
|
|
|
|
void main() {
|
|
const uint idx = get_idx();
|
|
|
|
if (idx >= p.ne) {
|
|
return;
|
|
}
|
|
|
|
const uint i03 = fastdiv(idx, p.ne0_012mp, fastdiv_L(p.ne0_Ls, 0));
|
|
const uint i03_offset = i03 * p.ne02*p.ne01*p.ne00;
|
|
const uint i02 = fastdiv(idx - i03_offset, p.ne0_01mp, fastdiv_L(p.ne0_Ls, 1));
|
|
const uint i02_offset = i02*p.ne01*p.ne00;
|
|
const uint i01 = fastdiv(idx - i03_offset - i02_offset, p.ne0_0mp, fastdiv_L(p.ne0_Ls, 2));
|
|
const uint i00 = idx - i03_offset - i02_offset - i01*p.ne00;
|
|
|
|
int param = floatBitsToInt(p.param1);
|
|
bool pass = false;
|
|
switch (param) {
|
|
case GGML_TRI_TYPE_UPPER_DIAG: pass = i00 >= i01; break;
|
|
case GGML_TRI_TYPE_UPPER: pass = i00 > i01; break;
|
|
case GGML_TRI_TYPE_LOWER_DIAG: pass = i00 <= i01; break;
|
|
case GGML_TRI_TYPE_LOWER: pass = i00 < i01; break;
|
|
}
|
|
|
|
if (pass) {
|
|
const float val = float(data_a[get_aoffset() + src0_idx(idx)]);
|
|
data_d[get_doffset() + dst_idx(idx)] = D_TYPE(val);
|
|
} else {
|
|
data_d[get_doffset() + dst_idx(idx)] = D_TYPE(0);
|
|
}
|
|
}
|