cubecl-wgpu 0.11.0-pre.3

WGPU runtime for the CubeCL
Documentation
use cubecl_core::prelude::polyfills::bitwise::*;
use cubecl_ir::{dialect::bitwise::*, interfaces::TypedExt, prelude::*, types::VectorType};
use pliron::builtin::types::{IntegerType, Signedness};

use crate::compiler::wgsl::{
    lower::lower_unop,
    to_wgsl::{TypeExtWgsl, wgsl_op_with_out},
};

wgsl_op_with_out!(BitwiseAndOp; |op, ctx| {
    format!("{} & {}", op.lhs(ctx).name(ctx), op.rhs(ctx).name(ctx))
});
wgsl_op_with_out!(BitwiseOrOp; |op, ctx| {
    format!("{} | {}", op.lhs(ctx).name(ctx), op.rhs(ctx).name(ctx))
});
wgsl_op_with_out!(BitwiseXorOp; |op, ctx| {
    format!("{} ^ {}", op.lhs(ctx).name(ctx), op.rhs(ctx).name(ctx))
});

wgsl_op_with_out!(ShiftLeftOp; |op, ctx| {
    let u32 = u32_ty(ctx, op.lhs(ctx)).to_wgsl(ctx);
    format!("{} << {u32}({})", op.lhs(ctx).name(ctx), op.rhs(ctx).name(ctx))
});
wgsl_op_with_out!(ShiftRightOp; |op, ctx| {
    let u32 = u32_ty(ctx, op.lhs(ctx)).to_wgsl(ctx);
    format!("{} >> {u32}({})", op.lhs(ctx).name(ctx), op.rhs(ctx).name(ctx))
});

wgsl_op_with_out!(BitwiseNotOp; |op, ctx| {
    format!("~{}", op.input(ctx).name(ctx))
});

wgsl_op_with_out!(CountOnesOp; |op, ctx| {
    let u32 = u32_ty(ctx, op.input(ctx)).to_wgsl(ctx);
    format!("{u32}(countOneBits({}))", op.input(ctx).name(ctx))
});
wgsl_op_with_out!(ReverseBitsOp; |op, ctx| {
    format!("reverseBits({})", op.input(ctx).name(ctx))
});
wgsl_op_with_out!(LeadingZerosBitsOp; |op, ctx| {
    let u32 = u32_ty(ctx, op.input(ctx)).to_wgsl(ctx);
    format!("{u32}(countLeadingZeros({}))", op.input(ctx).name(ctx))
});
wgsl_op_with_out!(TrailingZerosBitsOp; |op, ctx| {
    let u32 = u32_ty(ctx, op.input(ctx)).to_wgsl(ctx);
    format!("{u32}(countTrailingZeros({}))", op.input(ctx).name(ctx))
});
wgsl_op_with_out!(FindFirstSetOp; |op, ctx| {
    let u32 = u32_ty(ctx, op.input(ctx)).to_wgsl(ctx);
    format!("{u32}(firstTrailingBit({})) + {u32}(1)", op.input(ctx).name(ctx))
});

lower_unop!(LeadingZerosBitsOp, u64_leading_zeros, |op, ctx| {
    op.input(ctx).scalar_ty(ctx).is_int_of_width(ctx, 64)
});
lower_unop!(TrailingZerosBitsOp, u64_trailing_zeros, |op, ctx| {
    op.input(ctx).scalar_ty(ctx).is_int_of_width(ctx, 64)
});
lower_unop!(FindFirstSetOp, u64_ffs, |op, ctx| {
    op.input(ctx).scalar_ty(ctx).is_int_of_width(ctx, 64)
});

fn u32_ty(ctx: &Context, reference_ty: impl Typed) -> TypeHandle {
    let vec = reference_ty.vector_size(ctx);
    let u32 = IntegerType::get(ctx, 32, Signedness::Unsigned).to_handle();
    if vec > 1 {
        VectorType::get(ctx, u32, vec).to_handle()
    } else {
        u32
    }
}