-
Notifications
You must be signed in to change notification settings - Fork 1
Description
Idea
It would be great to support vamp-ir's [] abstraction
// k-bit xor and
def xor[k] x y -> z { ... }
def and[k] x y -> z { ... }where [k] means the xor function takes a constant integer to compile with. For Alucard, this would ideally be inferred, however we can explicitly declare it with the constant field in the circuit signature.
Further I think as we wish to write more complex circuits a compile-time will allow us to serve a circuit that is paramatarized over a common lisp value, that we must supply when extracting.
This can be very useful for testing certain behaviors when extracting or for grabbing round data from disk and supplying them before generating out the circuit.
For example
(deftype point ()
(x int)
(y int))
(deftype nested ()
(plane point)
(time point))
(defcircuit root-test ((public root int)
(constant field))
(= (bit-or field (* 3 root) 214)
0))
(defcircuit record-test ((public root int)
(private planer nested)
(constant bit-size)
(compile-time hash-round-data)
(output nested))
;; apply is a normal CL function
(apply #'and
(bit-xor bit-size root (x (plane planer)))
;; mapcar is also a CL function, the rest are all alucard
;; functions/values!
(mapcar (lambda (constant-from-disk)
(root-test constant-from-disk root))
hash-round-data)))Note :: at the bottom of this issue we discuss alternative syntax to compile-time.
could be an example of using constant to setup a root-test. And a compile-time hash-round-data to read hash round constants off disk to plant them in the circuit, which we then require to hold true by the and that is called upon the given equations.
Compilation Technique
For constant not much has to change, simply the vamp-ir layer needs to be notified of this, and we need to make sure that we can't place an intermediate value in the place where a constant value is taken.
Some shuffling will have to be done if constant are not the first argument due to how vamp-ir holds it's arguments, but that is less of an issue.
For compile-time a bit more will have to change. As our storage mechanism will have to be either a constraint as it is now, or a CL lambda which evaluates to a constraint. This means that we have to be careful during extraction, and extract with only the compile-time arguments given.
This makes the given syntax misleading as we have to supply only the compile-time values before extracting.
However once that issue is solved, all that has to be done is to make sure each circuit with compile-time arguments are handed them before running the pipeline
Syntax Challanges
This makes the proposed syntax misleading, as what we are doing is akin to
(defun generate (hash-round-data)
(defcircuit record-test ((public root int)
(private planer nested)
(constant bit-size)
(output nested))
(apply #'and
(bit-xor bit-size root (x (plane planer)))
(mapcar (lambda (constant-from-disk)
(root-test constant-from-disk root))
hash-round-data))))
(generate (read-from-disk ....))which would take no infrastructure change on my side to support (In fact this pattern works currently, but sadly redefines what the circuit is on every generate call...).
I'm unsure of how to effectively communicate this with the current diesgn, maybe something along the lines of a let over the cirucit would be better?
(def-compile-time (hash-round-data)
(defcircuit record-test ((public root int)
(private planer nested)
(constant bit-size)
(output nested))
(apply #'and
(bit-xor bit-size root (x (plane planer)))
(mapcar (lambda (constant-from-disk)
(root-test constant-from-disk root))
hash-round-data))))