Documentation

LeanMlir.Verified.PgdGen

The PGD-step kernels — hand-typed StableHLO text #

genLinearPgdStep, genMlpPgdStep, genCnnPgdStep, genCifarPgdStep: one PGD step (forward, the softmax-CE input gradient, an L∞ or L2 step, projection onto the ε-ball, clip to [0,1]) as StableHLO text, for Verified.Attack's attacks. These are not rendered from a proven graph and no tie pins them: each follows the proven input-VJP's formula by hand (the formula is cited in its docstring), so they are unverified program code, like the reference MlirCodegen.

def softmaxCeSeed (lty rty : String) (expv : String := "%expv") :

The stable softmax-CE seed %g = softmax(%logits) − %onehot, row-wise over [bs, nClasses] logits of type lty (rty the per-row [bs] type). Reads %logits, %onehot, %ninf and %zero; expv names the exponential (the linear kernel's spelling is %exp).

Equations
  • One or more equations did not get rendered due to their size.
Instances For
    def pgdStepTail (bxd0 rty : String) (linf : Bool) (stp : String := "%stp") (pj1 : String := "%pj1") (clA : String := "%clA") (clB : String := "%clB") :

    Every PGD kernel's tail, from the input gradient %dx on: the α/0/1 broadcasts, the step and projection — L∞ (sign step, box-clip to x0 ± ε) or L2 (normalised step, rescale into the ε-ball) — then the clip to [0,1], the return and the closing braces. Reads %x, %x0, %dx, %alpha, %eps, %zero and %one. stp, pj1, clA and clB name the step, the L∞ lower clip and the two [0,1] clips (the linear kernel spells them %step, %c1, %c3, %c4).

    Equations
    • One or more equations did not get rendered due to their size.
    Instances For
      def genLinearPgdStep (bs d0 d1 : Nat) (eps alpha : Float) (linf : Bool) :

      PGD-step kernel for the linear classifier. forward → softmax-CE input gradient dx = (softmax(xW+b) − onehot)·Wᵀ (the formula of the linear input-VJP, written by hand) → step → project to the eps-ball around x0 → clip to [0,1]. linf := true: L∞ sign-step, box-clip to x0 ± eps. linf := false: L2 step on the per-sample normalised gradient, projection onto the L2 ball of radius eps around x0. Returns the advanced adversarial input x_adv. eps/alpha baked as constants (recompiled per sweep point). Invoked via the generic forwardF32 FFI with onehot+x0 in the params blob and nClasses := d0 (output size) — no new FFI/C shim. The whole PGD step runs on the GPU; the host just iterates.

      Equations
      • One or more equations did not get rendered due to their size.
      Instances For
        def genMlpPgdStep (bs d0 h d1 : Nat) (eps alpha : Float) (linf : Bool) :

        PGD-step kernel for the 2-hidden-layer MLP (d0→h→h→d1, ReLU). Forward (saving the pre-activations z0,z1) → the input gradient dx = ((g·W₂ᵀ ⊙ relu'(z₁))·W₁ᵀ ⊙ relu'(z₀))·W₀ᵀ, the formula of Proofs.mlpInputGrad written by hand (ReLU masks via compare GT/select, the codegen's idiom) → L∞/L2 step + projection. Returns x_adv.

        Instances For
          def genCnnPgdStep (bs : Nat) (eps alpha : Float) (linf : Bool) :

          PGD-step kernel for the verified MNIST CNN (conv 1→32 → relu → conv 32→32 → relu → maxpool 28→14 → flatten → dense 6272→512 → relu → 512→512 → relu → 512→10). Forward (saving every pre-activation + the maxpool input) → softmax-CE seed → the full input-VJP dx, mirroring verified_mlir/cnn_train_step.mlir's backward ops: dot_general adjoints + ReLU masks (compare GT/select), maxpool-back (select_and_scatter, scatter the pooled cotangent to the argmax cells), and the two conv input-VJPs (transpose-o,i + spatial reverse of the kernel, then the same padded conv). The train step stops at dz1 (it only needs weight grads); here we add the final conv1 input-VJP to reach dx over the pixels. Then the L∞ sign-step / L2 projected step + ε-ball project + [0,1] clip. Architecture is fixed; only bs/eps/alpha vary.

          Instances For
            def genCifarPgdStep (bs : Nat) (eps alpha : Float) (linf : Bool) :

            PGD-step kernel for the verified CIFAR-10 CNN — the deeper sibling of genCnnPgdStep (conv 3→32 → relu → conv 32→32 → relu → maxpool → conv 32→64 → relu → conv 64→64 → relu → maxpool → flatten(4096) → 512 → 512 → 10). Same recipe — forward (saving every pre-activation + both maxpool inputs) → softmax-CE seed → the full input-VJP dx, mirroring verified_mlir/cifar_train_step.mlir's backward (4 conv input-VJPs, 2 select_and_scatter maxpool-backs, ReLU masks, dense adjoints) + the final conv1 input-VJP the train step omits — then the L∞/L2 step + ε-ball project + [0,1] clip. 3-channel 32×32, bs/eps/alpha vary.

            Instances For