Skip to content

Commit

Permalink
Huff code is now dynamic
Browse files Browse the repository at this point in the history
  • Loading branch information
cy4n1d3-p1x3l committed Dec 11, 2023
1 parent 066bb94 commit 9f036c3
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 55 deletions.
4 changes: 4 additions & 0 deletions report.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
No files changed, compilation skipped

Running 1 test for test/FFT.t.sol:FFTTest
[FAIL. Reason: EvmError: Revert] test_fft_in_huff() (gas: 162259)
16 changes: 11 additions & 5 deletions src/FFT_implementation/FFT.huff
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
///@dev theta_t = pi/n

#define macro PUT_THETA_T() = takes(0) returns(1) {
[N]
N()
[PI]
div
}
Expand All @@ -20,6 +20,12 @@
sdiv
}

#define macro N()=takes(0) returns(1){
0x04 calldataload
0x04 add
calldataload
}

///@notice initialising the 4 test values of (x,y) in the memory
///@dev initialise the memory with real values at multiples of 0x40 starting from zero
///@dev and imaginary values at multiples of 0x40 starting from 0x20
Expand All @@ -40,7 +46,7 @@
///@dev the FFT macro updates the 4 test values in the memory with the final values of the FFT

#define macro FFT() = takes(0) returns(0) {
[N] // [k]
N() // [k]
PUT_PHI_T() // [Phi_t_im,Phi_t_re,k]
loop1:
dup3 // [k,Phi_t_im,Phi_t_re,n]
Expand Down Expand Up @@ -127,7 +133,7 @@
}

#define macro REVERSE_BITS() = takes(0) returns(0) {
[N] // [N]
N() // [N]
[X3] mul
LOG2() // [LOG2(N)]
SCALE_DOWN()
Expand Down Expand Up @@ -194,7 +200,7 @@
0x01 // [1,a,m]
add // [a+1,m]
dup1 // [a+1,a+1,m]
[N] // [N,a+1,a+1,m]
N() // [N,a+1,a+1,m]
gt // [N>a+1,a+1,m]
Looper_calc3
jumpi
Expand Down Expand Up @@ -310,7 +316,7 @@
add // [a+n,T_im,T_real,Phi_t_im,Phi_t_re,n,k]
dup1 // [a+n,a+n,T_im,T_real,Phi_t_im,Phi_t_re,n,k]
0x2200 mstore
[N] // [N,a+n,T_im,T_real,Phi_t_im,Phi_t_re,n,k]
N() // [N,a+n,T_im,T_real,Phi_t_im,Phi_t_re,n,k]
gt
LOOP_last
jumpi
Expand Down
123 changes: 77 additions & 46 deletions src/FFT_implementation/Wrapper.huff
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,95 @@
///@notice storing values as desired in the fft implementation

#define macro MEMORY_INIT() =takes(0) returns(0){
0x24 calldataload
0x80 add
0x04 add
dup1
calldataload //[im[3],off(im[3])]

// the offset of the last imaginary element
0x24 calldataload
0x04 add
N() 0x20 mul add

// the offset of the last real element
0x04 calldataload
0x80 add
0x04 add
swap1 //[im[3],off(re[3],off(im[3])]
dup2
calldataload //[re[3],im[3],off(re[3],off(im[3])]
0x20 dup5 sub
calldataload //[im[2],re[3],im[3],off(re[3],off(im[3])]
0x20 dup5 sub
calldataload //[re[2],im[2],re[3],im[3],off(re[3],off(im[3])]
0x40 dup7 sub
calldataload //[im[1],re[2],im[2],re[3],im[3],off(re[3],off(im[3])]
0x40 dup7 sub
calldataload //[re[1],im[1],re[2],im[2],re[3],im[3],off(re[3],off(im[3])]
0x60 dup9 sub
calldataload //[im[0].re[1],im[1],re[2],im[2],re[3],im[3],off(re[3],off(im[3])]
0x60 dup9 sub
calldataload //[re[0],im[0].re[1],im[1],re[2],im[2],re[3],im[3],off(re[3],off(im[3])]
0x00 mstore
0x20 mstore
0x40 mstore
0x60 mstore
0x80 mstore
0xa0 mstore
0xc0 mstore
0xe0 mstore
N() 0x20 mul add //[off(re[n-1],off(im[n-1])]

loop1:
swap1
dup1 calldataload
swap2 dup1
calldataload
swap2
0x20 swap1 sub
swap1
0x20 swap1 sub
dup1
0x44 lt
loop1
jumpi
pop pop

0x00
N() 0x40 mul
loop2:
swap2 dup2 mstore
0x20 add
swap1 dup1 dup3
lt
loop2 jumpi
pop pop
}

#define macro RETURN_MEMORY()=takes(0) returns(0){
0xe0 mload
0xa0 mload
0x60 mload
0x20 mload
0xc0 mload
0x80 mload
0x40 mload
0x00 mload
0x00 mstore
0x20 mstore
0x40 mstore
0x60 mstore
0x80 mstore
0xa0 mstore
0xc0 mstore
0xe0 mstore

// loading all the imaginary numbers into memory
0x01 N() sub 0x40 mul 0x20 add
loop1:
dup1
mload
swap1
0x40 swap1 sub
0x00 dup2
sgt
loop1
jumpi
pop
N()

// loading all their real counterparts into memory
dup1 0x40 mul
loop2:
0x40 swap1 sub
dup1
mload
swap1
0x00 dup2
eq iszero
loop2
jumpi
pop
N()

// the offset foor the lengths of the arrays
dup1 0x20 mul 0x60 add
0x40

// storing the elements in sequential order
0x00
N() 0x20 mul dup1 add 0x80 add
loop3:
swap2 dup2 mstore
0x20 add
swap1 dup1 dup3
lt
loop3 jumpi
pop pop
}

#define macro FFT_LOCAL() =takes(0) returns (0){
MEMORY_INIT()
FFT()
RETURN_MEMORY()
0x100 0x00 return
N() 0x20 mul dup1 add 0x80 add
0x00 return
}

#define macro MAIN()= takes (0) returns (0){
Expand Down
47 changes: 43 additions & 4 deletions test/FFT.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ contract FFTTest is Test {
assertApproxEqAbs(sinVal, cosVal, 1e15);
}

function test_fft_in_huff() public {
function test_fft_in_huff1() public {
real_part.push(1 * 1e18);
real_part.push(-1 * 1e18);
real_part.push(0 * 1e18);
Expand All @@ -95,8 +95,8 @@ contract FFTTest is Test {
complex_part.push(0 * 1e18);
complex_part.push(1 * 1e18);
complex_part.push(-1 * 1e18);
int256[4] memory re;
int256[4] memory im;
int256[] memory re;
int256[] memory im;
(re, im) = fft_huff.fft(real_part, complex_part);
assertApproxEqAbs(re[0], 0 * 1e18, 1e15);
assertApproxEqAbs(im[0], 0 * 1e18, 1e15);
Expand All @@ -107,8 +107,47 @@ contract FFTTest is Test {
assertApproxEqAbs(re[3], 0 * 1e18, 1e15);
assertApproxEqAbs(im[3], -2 * 1e18, 1e15);
}

function test_fft_in_huff2() public {
real_part.push(1 * 1e18);
real_part.push(-1 * 1e18);
real_part.push(0 * 1e18);
real_part.push(0 * 1e18);
real_part.push(1 * 1e18);
real_part.push(2 * 1e18);
real_part.push(3 * 1e18);
real_part.push(2 * 1e18);
complex_part.push(0 * 1e18);
complex_part.push(0 * 1e18);
complex_part.push(1 * 1e18);
complex_part.push(-1 * 1e18);
complex_part.push(0 * 1e18);
complex_part.push(1 * 1e18);
complex_part.push(3 * 1e18);
complex_part.push(0 * 1e18);
assertEq(real_part.length, 8);
int256[] memory re;
int256[] memory im;
(re, im) = fft_huff.fft(real_part, complex_part);
assertApproxEqAbs(re[0], 8 * 1e18, 1e15);
assertApproxEqAbs(im[0], 4 * 1e18, 1e15);
assertApproxEqAbs(re[1], -4.121 * 1e18, 1e15);
assertApproxEqAbs(im[1], 6.535 * 1e18, 1e15);
assertApproxEqAbs(re[2], 1 * 1e18, 1e15);
assertApproxEqAbs(im[2], -3 * 1e18, 1e15);
assertApproxEqAbs(re[3], 1.292 * 1e18, 1e15);
assertApproxEqAbs(im[3], 0.535 * 1e18, 1e15);
assertApproxEqAbs(re[4], 2 * 1e18, 1e15);
assertApproxEqAbs(im[4], 4 * 1e18, 1e15);
assertApproxEqAbs(re[5], 0.1213 * 1e18, 1e15);
assertApproxEqAbs(im[5], -0.5355 * 1e18, 1e15);
assertApproxEqAbs(re[6], -3 * 1e18, 1e15);
assertApproxEqAbs(im[6], -5 * 1e18, 1e15);
assertApproxEqAbs(re[7], 2.7071 * 1e18, 1e15);
assertApproxEqAbs(im[7], -6.5355 * 1e18, 1e15);
}
}

interface Wrapper {
function fft(int256[] memory, int256[] memory) external returns (int256[4] memory, int256[4] memory);
function fft(int256[] memory, int256[] memory) external returns (int256[] memory, int256[] memory);
}

0 comments on commit 9f036c3

Please sign in to comment.