// File: dsharlet[P]array/test/ein_reduce.cpp
// Function: nda::test_ein_reduce_dft_body()
TEST(ein_reduce_dft) {
  constexpr index_t N = 30;
  vector<float, N> x;
  fill_pattern(x);

  // Compute the DFT by multiplying by a function computing the DFT matrix.
  // This isn't fast, but it's a fun test of a reduction with a different
  // type than the operands.
  vector<std::complex<float>, N> X({}, 0.0f);
  ein_reduce(ein<j>(X) += ein<j, k>(W<N>) * ein<k>(x));

  const float tolerance = 1e-3f;
  for (index_t j = 0; j < N; j++) {
    std::complex<float> X_j_ref = 0.0f;
    for (index_t k = 0; k < N; k++) {
      X_j_ref += W<N>(j, k) * x(k);
    }
    ASSERT_LT(abs(X_j_ref - X(j)), tolerance);
  }
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x460, %rsp            # imm = 0x460
movq $0x1e, -0x50(%rbp)
leaq -0x80(%rbp), %rdi
movq %rdi, -0x380(%rbp)
callq 0xc89b0
movq -0x380(%rbp), %rdi
xorps %xmm0, %xmm0
callq 0xc89e0
jmp 0xb4324
leaq -0xd0(%rbp), %rdi
callq 0xc8a20
jmp 0xb4332
leaq -0xd8(%rbp), %rdi
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0xc8a40
jmp 0xb4346
leaq -0xc0(%rbp), %rdi
leaq -0xd0(%rbp), %rsi
leaq -0xd8(%rbp), %rdx
callq 0xc8a70
jmp 0xb4362
leaq 0x147a7(%rip), %rdi     # 0xc8b10
callq 0xc8ae0
movq %rax, -0x388(%rbp)
jmp 0xb4377
movq -0x388(%rbp), %rax
movq %rax, -0x138(%rbp)
leaq -0x150(%rbp), %rdi
leaq -0x80(%rbp), %rsi
callq 0xc8c60
jmp 0xb4397
leaq -0x130(%rbp), %rdi
leaq -0x138(%rbp), %rsi
leaq -0x150(%rbp), %rdx
callq 0xc8c10
jmp 0xb43b3
leaq -0x168(%rbp), %rdi
leaq -0xc0(%rbp), %rsi
callq 0xc8ca0
jmp 0xb43c8
leaq -0x110(%rbp), %rdi
leaq -0x168(%rbp), %rsi
leaq -0x130(%rbp), %rdx
callq 0xc8ce0
jmp 0xb43e4
leaq -0x180(%rbp), %rax
movq %rax, -0x8(%rbp)
leaq -0x110(%rbp), %rax
movq %rax, -0x10(%rbp)
movq $0x3, -0x18(%rbp)
movq -0x10(%rbp), %rdx
movq %rdx, %r8
addq $0x18, %r8
leaq -0x40(%rbp), %rdi
leaq -0x41(%rbp), %rsi
leaq -0x42(%rbp), %rcx
callq 0xc2d80
jmp 0xb4420
movq -0x10(%rbp), %rsi
leaq -0x40(%rbp), %rdi
callq 0xc32f0
jmp 0xb442f
movq -0x10(%rbp), %rax
movq (%rax), %rcx
movq %rcx, -0x180(%rbp)
movq 0x8(%rax), %rcx
movq %rcx, -0x178(%rbp)
movq 0x10(%rax), %rax
movq %rax, -0x170(%rbp)
movss 0x135455(%rip), %xmm0   # 0x1e98b0
movss %xmm0, -0x184(%rbp)
movq $0x0, -0x190(%rbp)
cmpq $0x1e, -0x190(%rbp)
jge 0xb4844
leaq -0x198(%rbp), %rdi
xorps %xmm1, %xmm1
movaps %xmm1, %xmm0
callq 0xc8a40
jmp 0xb4490
movq $0x0, -0x1a0(%rbp)
cmpq $0x1e, -0x1a0(%rbp)
jge 0xb4578
cvtsi2ssq -0x190(%rbp), %xmm0
cvtsi2ssq -0x1a0(%rbp), %xmm1
callq 0xc8b10
movaps %xmm0, -0x3a0(%rbp)
jmp 0xb44c9
movaps -0x3a0(%rbp), %xmm0
movlpd %xmm0, -0x1b0(%rbp)
movq -0x1a0(%rbp), %rsi
leaq -0x80(%rbp), %rdi
callq 0xc8d60
movq %rax, -0x3a8(%rbp)
jmp 0xb44f1
movq -0x3a8(%rbp), %rsi
leaq -0x1b0(%rbp), %rdi
callq 0xc8d20
movaps %xmm0, -0x3c0(%rbp)
jmp 0xb450d
movaps -0x3c0(%rbp), %xmm0
movlpd %xmm0, -0x1a8(%rbp)
leaq -0x198(%rbp), %rdi
leaq -0x1a8(%rbp), %rsi
callq 0xc8da0
jmp 0xb4531
jmp 0xb4533
movq -0x1a0(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x1a0(%rbp)
jmp 0xb449b
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0xb486e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0xb4862
movq -0x190(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
callq 0xc8e80
movq %rax, -0x3c8(%rbp)
jmp 0xb4594
movq -0x3c8(%rbp), %rsi
leaq -0x198(%rbp), %rdi
callq 0xc8e40
movaps %xmm0, -0x3e0(%rbp)
jmp 0xb45b0
movaps -0x3e0(%rbp), %xmm0
movlpd %xmm0, -0x348(%rbp)
leaq -0x348(%rbp), %rdi
callq 0xc8e00
movss %xmm0, -0x3e4(%rbp)
jmp 0xb45d5
movss -0x3e4(%rbp), %xmm1
movss 0x1352cb(%rip), %xmm0   # 0x1e98b0
ucomiss %xmm1, %xmm0
seta %al
movb %al, -0x3f1(%rbp)
leaq -0x369(%rbp), %rdi
movq %rdi, -0x3f0(%rbp)
callq 0x33b0
movq -0x3f0(%rbp), %rdx
leaq 0x13585f(%rip), %rsi    # 0x1e9e71
leaq -0x368(%rbp), %rdi
callq 0x10a90
jmp 0xb4620
movb -0x3f1(%rbp), %al
movzbl %al, %esi
andl $0x1, %esi
leaq -0x340(%rbp), %rdi
leaq -0x368(%rbp), %rdx
callq 0x10f80
jmp 0xb4641
leaq 0x12819d(%rip), %rsi    # 0x1dc7e5
leaq -0x340(%rbp), %rdi
callq 0x34320
movq %rax, -0x400(%rbp)
jmp 0xb465d
movq -0x400(%rbp), %rdi
leaq 0x135826(%rip), %rsi    # 0x1e9e91
callq 0x35580
movq %rax, -0x408(%rbp)
jmp 0xb4679
movq -0x408(%rbp), %rdi
leaq 0x12c125(%rip), %rsi    # 0x1e07ac
callq 0x34320
movq %rax, -0x410(%rbp)
jmp 0xb4695
movq -0x190(%rbp), %rsi
leaq -0xc0(%rbp), %rdi
callq 0xc8e80
movq %rax, -0x418(%rbp)
jmp 0xb46b1
movq -0x418(%rbp), %rsi
leaq -0x198(%rbp), %rdi
callq 0xc8e40
movaps %xmm0, -0x430(%rbp)
jmp 0xb46cd
movaps -0x430(%rbp), %xmm0
movlpd %xmm0, -0x378(%rbp)
leaq -0x378(%rbp), %rdi
callq 0xc8e00
movss %xmm0, -0x434(%rbp)
jmp 0xb46f2
movq -0x410(%rbp), %rdi
movss -0x434(%rbp), %xmm0
movss %xmm0, -0x370(%rbp)
leaq -0x370(%rbp), %rsi
callq 0x96bd0
movq %rax, -0x440(%rbp)
jmp 0xb471e
movq -0x440(%rbp), %rdi
leaq 0x1280b9(%rip), %rsi    # 0x1dc7e5
callq 0x34320
movq %rax, -0x448(%rbp)
jmp 0xb473a
movq -0x448(%rbp), %rdi
leaq 0x13573f(%rip), %rsi    # 0x1e9e87
callq 0x344d0
movq %rax, -0x450(%rbp)
jmp 0xb4756
movq -0x450(%rbp), %rdi
leaq 0x12c048(%rip), %rsi    # 0x1e07ac
callq 0x34320
movq %rax, -0x458(%rbp)
jmp 0xb4772
movq -0x458(%rbp), %rdi
leaq -0x184(%rbp), %rsi
callq 0x96bd0
movq %rax, -0x460(%rbp)
jmp 0xb478e
movq -0x460(%rbp), %rdi
leaq 0x141cdf(%rip), %rsi    # 0x1f647b
callq 0x34320
jmp 0xb47a3
leaq -0x340(%rbp), %rdi
callq 0x10ff0
jmp 0xb47b1
leaq -0x368(%rbp), %rdi
callq 0x3100
leaq -0x369(%rbp), %rdi
callq 0x3290
movq -0x190(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x190(%rbp)
jmp 0xb446e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0xb4836
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
jmp 0xb482a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x88(%rbp)
movl %eax, -0x8c(%rbp)
leaq -0x340(%rbp), %rdi
callq 0x10ff0
jmp 0xb4828
jmp 0xb482a
leaq -0x368(%rbp), %rdi
callq 0x3100
leaq -0x369(%rbp), %rdi
callq 0x3290
jmp 0xb4862
leaq -0xc0(%rbp), %rdi
callq 0xc8ec0
leaq -0x80(%rbp), %rdi
callq 0xc8f00
addq $0x460, %rsp            # imm = 0x460
popq %rbp
retq
leaq -0xc0(%rbp), %rdi
callq 0xc8ec0
leaq -0x80(%rbp), %rdi
callq 0xc8f00
movq -0x88(%rbp), %rdi
callq 0x33a0
movq %rax, %rdi
callq 0x116d0
nopl (%rax,%rax)