#line 1 "numpy/core/src/multiarray/einsum_sumprod.c.src"

/*
 *****************************************************************************
 **       This file was autogenerated from a template  DO NOT EDIT!!!!      **
 **       Changes should be made to the original source (.src) file         **
 *****************************************************************************
 */

#line 1
/*
 * This file provides optimized sum of product implementations used internally
 * by einsum.
 *
 * Copyright (c) 2011 by Mark Wiebe (mwwiebe@gmail.com)
 * The University of British Columbia
 *
 * See LICENSE.txt for the license.
 */

#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#define _MULTIARRAYMODULE

#include <numpy/npy_common.h>
#include <numpy/ndarraytypes.h>  /* for NPY_NTYPES */
#include <numpy/halffloat.h>

#include "einsum_sumprod.h"
#include "einsum_debug.h"
#include "simd/simd.h"
#include "common.h"

// ARM/Neon don't have instructions for aligned memory access
#ifdef NPY_HAVE_NEON
    #define EINSUM_IS_ALIGNED(x) 0
#else
    #define EINSUM_IS_ALIGNED(x) npy_is_aligned(x, NPY_SIMD_WIDTH)
#endif

/**********************************************/

#line 74

#if !0
static NPY_GCC_OPT_3 npy_byte byte_sum_of_arr(npy_byte *data, npy_intp count)
{
    npy_byte accum = 0;
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_s8;
    npyv_s8 v_accum = npyv_zero_s8();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_s8 a0 = npyv_loada_s8(data + vstep * 0);
            
#line 96
            npyv_s8 a1 = npyv_loada_s8(data + vstep * 1);
            
#line 96
            npyv_s8 a2 = npyv_loada_s8(data + vstep * 2);
            
#line 96
            npyv_s8 a3 = npyv_loada_s8(data + vstep * 3);
            
            npyv_s8 a01   = npyv_add_s8(a0, a1);
            npyv_s8 a23   = npyv_add_s8(a2, a3);
            npyv_s8 a0123 = npyv_add_s8(a01, a23);
                     v_accum = npyv_add_s8(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_s8 a0 = npyv_load_s8(data + vstep * 0);
            
#line 96
            npyv_s8 a1 = npyv_load_s8(data + vstep * 1);
            
#line 96
            npyv_s8 a2 = npyv_load_s8(data + vstep * 2);
            
#line 96
            npyv_s8 a3 = npyv_load_s8(data + vstep * 3);
            
            npyv_s8 a01   = npyv_add_s8(a0, a1);
            npyv_s8 a23   = npyv_add_s8(a2, a3);
            npyv_s8 a0123 = npyv_add_s8(a01, a23);
                     v_accum = npyv_add_s8(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data, count);
        v_accum = npyv_add_s8(a, v_accum);
    }
    accum = npyv_sum_s8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_byte a01 = (*data) + (data[1]);
        const npy_byte a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_byte
    return accum;
}
#endif

#line 131
static void
byte_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_byte *)data_out = ((*(npy_byte *)data0) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_byte *)data_out = ((*(npy_byte *)data0) *
                                         (*(npy_byte *)data1) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_byte *)data_out = ((*(npy_byte *)data0) *
                                         (*(npy_byte *)data1) *
                                         (*(npy_byte *)data2) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        *(npy_byte *)dataptr[nop] = (temp +
                                           (*(npy_byte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_byte *)data_out)[0] = ((npy_byte *)data0)[0] +
                                         ((npy_byte *)data_out)[0];
        ((npy_byte *)data_out)[1] = ((npy_byte *)data0)[1] +
                                         ((npy_byte *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_byte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_byte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
byte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data_out = (npy_byte *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_byte *)data_out + 2*6)[0] =
                                    ((npy_byte *)data0 + 2*6)[0] +
                                    ((npy_byte *)data_out + 2*6)[0];
            ((npy_byte *)data_out + 2*6)[1] =
                                    ((npy_byte *)data0 + 2*6)[1] +
                                    ((npy_byte *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_byte *)data_out + 2*5)[0] =
                                    ((npy_byte *)data0 + 2*5)[0] +
                                    ((npy_byte *)data_out + 2*5)[0];
            ((npy_byte *)data_out + 2*5)[1] =
                                    ((npy_byte *)data0 + 2*5)[1] +
                                    ((npy_byte *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_byte *)data_out + 2*4)[0] =
                                    ((npy_byte *)data0 + 2*4)[0] +
                                    ((npy_byte *)data_out + 2*4)[0];
            ((npy_byte *)data_out + 2*4)[1] =
                                    ((npy_byte *)data0 + 2*4)[1] +
                                    ((npy_byte *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_byte *)data_out + 2*3)[0] =
                                    ((npy_byte *)data0 + 2*3)[0] +
                                    ((npy_byte *)data_out + 2*3)[0];
            ((npy_byte *)data_out + 2*3)[1] =
                                    ((npy_byte *)data0 + 2*3)[1] +
                                    ((npy_byte *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_byte *)data_out + 2*2)[0] =
                                    ((npy_byte *)data0 + 2*2)[0] +
                                    ((npy_byte *)data_out + 2*2)[0];
            ((npy_byte *)data_out + 2*2)[1] =
                                    ((npy_byte *)data0 + 2*2)[1] +
                                    ((npy_byte *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_byte *)data_out + 2*1)[0] =
                                    ((npy_byte *)data0 + 2*1)[0] +
                                    ((npy_byte *)data_out + 2*1)[0];
            ((npy_byte *)data_out + 2*1)[1] =
                                    ((npy_byte *)data0 + 2*1)[1] +
                                    ((npy_byte *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_byte *)data_out + 2*0)[0] =
                                    ((npy_byte *)data0 + 2*0)[0] +
                                    ((npy_byte *)data_out + 2*0)[0];
            ((npy_byte *)data_out + 2*0)[1] =
                                    ((npy_byte *)data0 + 2*0)[1] +
                                    ((npy_byte *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_byte *)data_out + 2*0)[0] =
                                ((npy_byte *)data0 + 2*0)[0] +
                                ((npy_byte *)data_out + 2*0)[0];
        ((npy_byte *)data_out + 2*0)[1] =
                                ((npy_byte *)data0 + 2*0)[1] +
                                ((npy_byte *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_byte *)data_out + 2*1)[0] =
                                ((npy_byte *)data0 + 2*1)[0] +
                                ((npy_byte *)data_out + 2*1)[0];
        ((npy_byte *)data_out + 2*1)[1] =
                                ((npy_byte *)data0 + 2*1)[1] +
                                ((npy_byte *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_byte *)data_out + 2*2)[0] =
                                ((npy_byte *)data0 + 2*2)[0] +
                                ((npy_byte *)data_out + 2*2)[0];
        ((npy_byte *)data_out + 2*2)[1] =
                                ((npy_byte *)data0 + 2*2)[1] +
                                ((npy_byte *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_byte *)data_out + 2*3)[0] =
                                ((npy_byte *)data0 + 2*3)[0] +
                                ((npy_byte *)data_out + 2*3)[0];
        ((npy_byte *)data_out + 2*3)[1] =
                                ((npy_byte *)data0 + 2*3)[1] +
                                ((npy_byte *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_byte *)data_out + 2*4)[0] =
                                ((npy_byte *)data0 + 2*4)[0] +
                                ((npy_byte *)data_out + 2*4)[0];
        ((npy_byte *)data_out + 2*4)[1] =
                                ((npy_byte *)data0 + 2*4)[1] +
                                ((npy_byte *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_byte *)data_out + 2*5)[0] =
                                ((npy_byte *)data0 + 2*5)[0] +
                                ((npy_byte *)data_out + 2*5)[0];
        ((npy_byte *)data_out + 2*5)[1] =
                                ((npy_byte *)data0 + 2*5)[1] +
                                ((npy_byte *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_byte *)data_out + 2*6)[0] =
                                ((npy_byte *)data0 + 2*6)[0] +
                                ((npy_byte *)data_out + 2*6)[0];
        ((npy_byte *)data_out + 2*6)[1] =
                                ((npy_byte *)data0 + 2*6)[1] +
                                ((npy_byte *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_byte *)data_out + 2*7)[0] =
                                ((npy_byte *)data0 + 2*7)[0] +
                                ((npy_byte *)data_out + 2*7)[0];
        ((npy_byte *)data_out + 2*7)[1] =
                                ((npy_byte *)data0 + 2*7)[1] +
                                ((npy_byte *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
byte_sum_of_products_muladd(npy_byte *data, npy_byte *data_out, npy_byte scalar, npy_intp count)
{
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s8;
    const npyv_s8 v_scalar = npyv_setall_s8(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s8 b0 = npyv_loada_s8(data + vstep * 0);
            npyv_s8 c0 = npyv_loada_s8(data_out + vstep * 0);
            
#line 312
            npyv_s8 b1 = npyv_loada_s8(data + vstep * 1);
            npyv_s8 c1 = npyv_loada_s8(data_out + vstep * 1);
            
#line 312
            npyv_s8 b2 = npyv_loada_s8(data + vstep * 2);
            npyv_s8 c2 = npyv_loada_s8(data_out + vstep * 2);
            
#line 312
            npyv_s8 b3 = npyv_loada_s8(data + vstep * 3);
            npyv_s8 c3 = npyv_loada_s8(data_out + vstep * 3);
            
            #line 318
            npyv_s8 abc0 = npyv_muladd_s8(v_scalar, b0, c0);
            
#line 318
            npyv_s8 abc1 = npyv_muladd_s8(v_scalar, b1, c1);
            
#line 318
            npyv_s8 abc2 = npyv_muladd_s8(v_scalar, b2, c2);
            
#line 318
            npyv_s8 abc3 = npyv_muladd_s8(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s8 b0 = npyv_load_s8(data + vstep * 0);
            npyv_s8 c0 = npyv_load_s8(data_out + vstep * 0);
            
#line 312
            npyv_s8 b1 = npyv_load_s8(data + vstep * 1);
            npyv_s8 c1 = npyv_load_s8(data_out + vstep * 1);
            
#line 312
            npyv_s8 b2 = npyv_load_s8(data + vstep * 2);
            npyv_s8 c2 = npyv_load_s8(data_out + vstep * 2);
            
#line 312
            npyv_s8 b3 = npyv_load_s8(data + vstep * 3);
            npyv_s8 c3 = npyv_load_s8(data_out + vstep * 3);
            
            #line 318
            npyv_s8 abc0 = npyv_muladd_s8(v_scalar, b0, c0);
            
#line 318
            npyv_s8 abc1 = npyv_muladd_s8(v_scalar, b1, c1);
            
#line 318
            npyv_s8 abc2 = npyv_muladd_s8(v_scalar, b2, c2);
            
#line 318
            npyv_s8 abc3 = npyv_muladd_s8(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data, count);
        npyv_s8 b = npyv_load_tillz_s8(data_out, count);
        npyv_store_till_s8(data_out, count, npyv_muladd_s8(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_byte b0 = (data[0]);
        const npy_byte c0 = (data_out[0]);
        
#line 340
        const npy_byte b1 = (data[1]);
        const npy_byte c1 = (data_out[1]);
        
#line 340
        const npy_byte b2 = (data[2]);
        const npy_byte c2 = (data_out[2]);
        
#line 340
        const npy_byte b3 = (data[3]);
        const npy_byte c3 = (data_out[3]);
        
        #line 346
        const npy_byte abc0 = scalar * b0 + c0;
        
#line 346
        const npy_byte abc1 = scalar * b1 + c1;
        
#line 346
        const npy_byte abc2 = scalar * b2 + c2;
        
#line 346
        const npy_byte abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_byte b = (*data);
        const npy_byte c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_byte
}

static void
byte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data_out = (npy_byte *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_byte
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s8;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s8 a0 = npyv_loada_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_loada_s8(data1 + vstep * 0);
            npyv_s8 c0 = npyv_loada_s8(data_out + vstep * 0);
            
#line 390
            npyv_s8 a1 = npyv_loada_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_loada_s8(data1 + vstep * 1);
            npyv_s8 c1 = npyv_loada_s8(data_out + vstep * 1);
            
#line 390
            npyv_s8 a2 = npyv_loada_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_loada_s8(data1 + vstep * 2);
            npyv_s8 c2 = npyv_loada_s8(data_out + vstep * 2);
            
#line 390
            npyv_s8 a3 = npyv_loada_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_loada_s8(data1 + vstep * 3);
            npyv_s8 c3 = npyv_loada_s8(data_out + vstep * 3);
            
            #line 397
            npyv_s8 abc0 = npyv_muladd_s8(a0, b0, c0);
            
#line 397
            npyv_s8 abc1 = npyv_muladd_s8(a1, b1, c1);
            
#line 397
            npyv_s8 abc2 = npyv_muladd_s8(a2, b2, c2);
            
#line 397
            npyv_s8 abc3 = npyv_muladd_s8(a3, b3, c3);
            
            #line 402
            npyv_storea_s8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s8 a0 = npyv_load_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_load_s8(data1 + vstep * 0);
            npyv_s8 c0 = npyv_load_s8(data_out + vstep * 0);
            
#line 390
            npyv_s8 a1 = npyv_load_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_load_s8(data1 + vstep * 1);
            npyv_s8 c1 = npyv_load_s8(data_out + vstep * 1);
            
#line 390
            npyv_s8 a2 = npyv_load_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_load_s8(data1 + vstep * 2);
            npyv_s8 c2 = npyv_load_s8(data_out + vstep * 2);
            
#line 390
            npyv_s8 a3 = npyv_load_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_load_s8(data1 + vstep * 3);
            npyv_s8 c3 = npyv_load_s8(data_out + vstep * 3);
            
            #line 397
            npyv_s8 abc0 = npyv_muladd_s8(a0, b0, c0);
            
#line 397
            npyv_s8 abc1 = npyv_muladd_s8(a1, b1, c1);
            
#line 397
            npyv_s8 abc2 = npyv_muladd_s8(a2, b2, c2);
            
#line 397
            npyv_s8 abc3 = npyv_muladd_s8(a3, b3, c3);
            
            #line 402
            npyv_store_s8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data0, count);
        npyv_s8 b = npyv_load_tillz_s8(data1, count);
        npyv_s8 c = npyv_load_tillz_s8(data_out, count);
        npyv_store_till_s8(data_out, count, npyv_muladd_s8(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_byte a0 = (data0[0]);
        const npy_byte b0 = (data1[0]);
        const npy_byte c0 = (data_out[0]);
        
#line 420
        const npy_byte a1 = (data0[1]);
        const npy_byte b1 = (data1[1]);
        const npy_byte c1 = (data_out[1]);
        
#line 420
        const npy_byte a2 = (data0[2]);
        const npy_byte b2 = (data1[2]);
        const npy_byte c2 = (data_out[2]);
        
#line 420
        const npy_byte a3 = (data0[3]);
        const npy_byte b3 = (data1[3]);
        const npy_byte c3 = (data_out[3]);
        
        #line 427
        const npy_byte abc0 = a0 * b0 + c0;
        
#line 427
        const npy_byte abc1 = a1 * b1 + c1;
        
#line 427
        const npy_byte abc2 = a2 * b2 + c2;
        
#line 427
        const npy_byte abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_byte a = (*data0);
        const npy_byte b = (*data1);
        const npy_byte c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_byte

}

/* Some extra specializations for the two operand case */
static void
byte_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte value0 = (*(npy_byte *)dataptr[0]);
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data_out = (npy_byte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    byte_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
byte_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte value1 = (*(npy_byte *)dataptr[1]);
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data_out = (npy_byte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    byte_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte accum = 0;

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s8;
    npyv_s8 v_accum = npyv_zero_s8();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s8 a0 = npyv_loada_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_loada_s8(data1 + vstep * 0);
            
#line 501
            npyv_s8 a1 = npyv_loada_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_loada_s8(data1 + vstep * 1);
            
#line 501
            npyv_s8 a2 = npyv_loada_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_loada_s8(data1 + vstep * 2);
            
#line 501
            npyv_s8 a3 = npyv_loada_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_loada_s8(data1 + vstep * 3);
            
            npyv_s8 ab3 = npyv_muladd_s8(a3, b3, v_accum);
            npyv_s8 ab2 = npyv_muladd_s8(a2, b2, ab3);
            npyv_s8 ab1 = npyv_muladd_s8(a1, b1, ab2);
                   v_accum = npyv_muladd_s8(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s8 a0 = npyv_load_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_load_s8(data1 + vstep * 0);
            
#line 501
            npyv_s8 a1 = npyv_load_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_load_s8(data1 + vstep * 1);
            
#line 501
            npyv_s8 a2 = npyv_load_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_load_s8(data1 + vstep * 2);
            
#line 501
            npyv_s8 a3 = npyv_load_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_load_s8(data1 + vstep * 3);
            
            npyv_s8 ab3 = npyv_muladd_s8(a3, b3, v_accum);
            npyv_s8 ab2 = npyv_muladd_s8(a2, b2, ab3);
            npyv_s8 ab1 = npyv_muladd_s8(a1, b1, ab2);
                   v_accum = npyv_muladd_s8(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data0, count);
        npyv_s8 b = npyv_load_tillz_s8(data1, count);
        v_accum = npyv_muladd_s8(a, b, v_accum);
    }
    accum = npyv_sum_s8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_byte ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_byte ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_byte ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_byte ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_byte a = (*data0);
        const npy_byte b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_byte
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte value0 = (*(npy_byte *)dataptr[0]);
    npy_byte accum = byte_sum_of_arr(data1, count);
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte value1 = (*(npy_byte *)dataptr[1]);
    npy_byte accum = byte_sum_of_arr(data0, count);
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
byte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data2 = (npy_byte *)dataptr[2];
    npy_byte *data_out = (npy_byte *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
byte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        *(npy_byte *)dataptr[nop] = (temp +
                                           (*(npy_byte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_byte);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_byte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_byte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_byte);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_byte *data = (npy_byte *)dataptr[0];
    npy_byte accum = byte_sum_of_arr(data, count);
    *((npy_byte *)dataptr[1]) = (accum + (*((npy_byte *)dataptr[1])));
#else
    npy_byte accum_re = 0, accum_im = 0;
    npy_byte *data0 = (npy_byte *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_byte re01 = data0[0] + data0[2];
        const npy_byte re23 = data0[4] + data0[6];
        const npy_byte im13 = data0[1] + data0[3];
        const npy_byte im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_byte *)dataptr[1])[0] += accum_re;
    ((npy_byte *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
byte_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_byte accum_re = 0, accum_im = 0;
#else
    npy_byte accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_byte *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_byte *)data0) *
                 (*(npy_byte *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_byte *)data0) *
                 (*(npy_byte *)data1) *
                 (*(npy_byte *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_byte *)data0)[0];
        accum_im += ((npy_byte *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_byte *)dataptr[1])[0] += accum_re;
    ((npy_byte *)dataptr[1])[1] += accum_im;
#  else
    ((npy_byte *)dataptr[nop])[0] += accum_re;
    ((npy_byte *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_byte *)dataptr[1]) = (accum +
                                    (*((npy_byte *)dataptr[1])));
#  else
    *((npy_byte *)dataptr[nop]) = (accum +
                                    (*((npy_byte *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
byte_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_byte *)data_out = ((*(npy_byte *)data0) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_byte *)data_out = ((*(npy_byte *)data0) *
                                         (*(npy_byte *)data1) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_byte *)data_out = ((*(npy_byte *)data0) *
                                         (*(npy_byte *)data1) *
                                         (*(npy_byte *)data2) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        *(npy_byte *)dataptr[nop] = (temp +
                                           (*(npy_byte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_byte *)data_out)[0] = ((npy_byte *)data0)[0] +
                                         ((npy_byte *)data_out)[0];
        ((npy_byte *)data_out)[1] = ((npy_byte *)data0)[1] +
                                         ((npy_byte *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_byte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_byte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
byte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data_out = (npy_byte *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_byte *)data_out + 2*6)[0] =
                                    ((npy_byte *)data0 + 2*6)[0] +
                                    ((npy_byte *)data_out + 2*6)[0];
            ((npy_byte *)data_out + 2*6)[1] =
                                    ((npy_byte *)data0 + 2*6)[1] +
                                    ((npy_byte *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_byte *)data_out + 2*5)[0] =
                                    ((npy_byte *)data0 + 2*5)[0] +
                                    ((npy_byte *)data_out + 2*5)[0];
            ((npy_byte *)data_out + 2*5)[1] =
                                    ((npy_byte *)data0 + 2*5)[1] +
                                    ((npy_byte *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_byte *)data_out + 2*4)[0] =
                                    ((npy_byte *)data0 + 2*4)[0] +
                                    ((npy_byte *)data_out + 2*4)[0];
            ((npy_byte *)data_out + 2*4)[1] =
                                    ((npy_byte *)data0 + 2*4)[1] +
                                    ((npy_byte *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_byte *)data_out + 2*3)[0] =
                                    ((npy_byte *)data0 + 2*3)[0] +
                                    ((npy_byte *)data_out + 2*3)[0];
            ((npy_byte *)data_out + 2*3)[1] =
                                    ((npy_byte *)data0 + 2*3)[1] +
                                    ((npy_byte *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_byte *)data_out + 2*2)[0] =
                                    ((npy_byte *)data0 + 2*2)[0] +
                                    ((npy_byte *)data_out + 2*2)[0];
            ((npy_byte *)data_out + 2*2)[1] =
                                    ((npy_byte *)data0 + 2*2)[1] +
                                    ((npy_byte *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_byte *)data_out + 2*1)[0] =
                                    ((npy_byte *)data0 + 2*1)[0] +
                                    ((npy_byte *)data_out + 2*1)[0];
            ((npy_byte *)data_out + 2*1)[1] =
                                    ((npy_byte *)data0 + 2*1)[1] +
                                    ((npy_byte *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_byte *)data_out + 2*0)[0] =
                                    ((npy_byte *)data0 + 2*0)[0] +
                                    ((npy_byte *)data_out + 2*0)[0];
            ((npy_byte *)data_out + 2*0)[1] =
                                    ((npy_byte *)data0 + 2*0)[1] +
                                    ((npy_byte *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_byte *)data_out + 2*0)[0] =
                                ((npy_byte *)data0 + 2*0)[0] +
                                ((npy_byte *)data_out + 2*0)[0];
        ((npy_byte *)data_out + 2*0)[1] =
                                ((npy_byte *)data0 + 2*0)[1] +
                                ((npy_byte *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_byte *)data_out + 2*1)[0] =
                                ((npy_byte *)data0 + 2*1)[0] +
                                ((npy_byte *)data_out + 2*1)[0];
        ((npy_byte *)data_out + 2*1)[1] =
                                ((npy_byte *)data0 + 2*1)[1] +
                                ((npy_byte *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_byte *)data_out + 2*2)[0] =
                                ((npy_byte *)data0 + 2*2)[0] +
                                ((npy_byte *)data_out + 2*2)[0];
        ((npy_byte *)data_out + 2*2)[1] =
                                ((npy_byte *)data0 + 2*2)[1] +
                                ((npy_byte *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_byte *)data_out + 2*3)[0] =
                                ((npy_byte *)data0 + 2*3)[0] +
                                ((npy_byte *)data_out + 2*3)[0];
        ((npy_byte *)data_out + 2*3)[1] =
                                ((npy_byte *)data0 + 2*3)[1] +
                                ((npy_byte *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_byte *)data_out + 2*4)[0] =
                                ((npy_byte *)data0 + 2*4)[0] +
                                ((npy_byte *)data_out + 2*4)[0];
        ((npy_byte *)data_out + 2*4)[1] =
                                ((npy_byte *)data0 + 2*4)[1] +
                                ((npy_byte *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_byte *)data_out + 2*5)[0] =
                                ((npy_byte *)data0 + 2*5)[0] +
                                ((npy_byte *)data_out + 2*5)[0];
        ((npy_byte *)data_out + 2*5)[1] =
                                ((npy_byte *)data0 + 2*5)[1] +
                                ((npy_byte *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_byte *)data_out + 2*6)[0] =
                                ((npy_byte *)data0 + 2*6)[0] +
                                ((npy_byte *)data_out + 2*6)[0];
        ((npy_byte *)data_out + 2*6)[1] =
                                ((npy_byte *)data0 + 2*6)[1] +
                                ((npy_byte *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_byte *)data_out + 2*7)[0] =
                                ((npy_byte *)data0 + 2*7)[0] +
                                ((npy_byte *)data_out + 2*7)[0];
        ((npy_byte *)data_out + 2*7)[1] =
                                ((npy_byte *)data0 + 2*7)[1] +
                                ((npy_byte *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
byte_sum_of_products_muladd(npy_byte *data, npy_byte *data_out, npy_byte scalar, npy_intp count)
{
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s8;
    const npyv_s8 v_scalar = npyv_setall_s8(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s8 b0 = npyv_loada_s8(data + vstep * 0);
            npyv_s8 c0 = npyv_loada_s8(data_out + vstep * 0);
            
#line 312
            npyv_s8 b1 = npyv_loada_s8(data + vstep * 1);
            npyv_s8 c1 = npyv_loada_s8(data_out + vstep * 1);
            
#line 312
            npyv_s8 b2 = npyv_loada_s8(data + vstep * 2);
            npyv_s8 c2 = npyv_loada_s8(data_out + vstep * 2);
            
#line 312
            npyv_s8 b3 = npyv_loada_s8(data + vstep * 3);
            npyv_s8 c3 = npyv_loada_s8(data_out + vstep * 3);
            
            #line 318
            npyv_s8 abc0 = npyv_muladd_s8(v_scalar, b0, c0);
            
#line 318
            npyv_s8 abc1 = npyv_muladd_s8(v_scalar, b1, c1);
            
#line 318
            npyv_s8 abc2 = npyv_muladd_s8(v_scalar, b2, c2);
            
#line 318
            npyv_s8 abc3 = npyv_muladd_s8(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s8 b0 = npyv_load_s8(data + vstep * 0);
            npyv_s8 c0 = npyv_load_s8(data_out + vstep * 0);
            
#line 312
            npyv_s8 b1 = npyv_load_s8(data + vstep * 1);
            npyv_s8 c1 = npyv_load_s8(data_out + vstep * 1);
            
#line 312
            npyv_s8 b2 = npyv_load_s8(data + vstep * 2);
            npyv_s8 c2 = npyv_load_s8(data_out + vstep * 2);
            
#line 312
            npyv_s8 b3 = npyv_load_s8(data + vstep * 3);
            npyv_s8 c3 = npyv_load_s8(data_out + vstep * 3);
            
            #line 318
            npyv_s8 abc0 = npyv_muladd_s8(v_scalar, b0, c0);
            
#line 318
            npyv_s8 abc1 = npyv_muladd_s8(v_scalar, b1, c1);
            
#line 318
            npyv_s8 abc2 = npyv_muladd_s8(v_scalar, b2, c2);
            
#line 318
            npyv_s8 abc3 = npyv_muladd_s8(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data, count);
        npyv_s8 b = npyv_load_tillz_s8(data_out, count);
        npyv_store_till_s8(data_out, count, npyv_muladd_s8(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_byte b0 = (data[0]);
        const npy_byte c0 = (data_out[0]);
        
#line 340
        const npy_byte b1 = (data[1]);
        const npy_byte c1 = (data_out[1]);
        
#line 340
        const npy_byte b2 = (data[2]);
        const npy_byte c2 = (data_out[2]);
        
#line 340
        const npy_byte b3 = (data[3]);
        const npy_byte c3 = (data_out[3]);
        
        #line 346
        const npy_byte abc0 = scalar * b0 + c0;
        
#line 346
        const npy_byte abc1 = scalar * b1 + c1;
        
#line 346
        const npy_byte abc2 = scalar * b2 + c2;
        
#line 346
        const npy_byte abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_byte b = (*data);
        const npy_byte c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_byte
}

static void
byte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data_out = (npy_byte *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_byte
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s8;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s8 a0 = npyv_loada_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_loada_s8(data1 + vstep * 0);
            npyv_s8 c0 = npyv_loada_s8(data_out + vstep * 0);
            
#line 390
            npyv_s8 a1 = npyv_loada_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_loada_s8(data1 + vstep * 1);
            npyv_s8 c1 = npyv_loada_s8(data_out + vstep * 1);
            
#line 390
            npyv_s8 a2 = npyv_loada_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_loada_s8(data1 + vstep * 2);
            npyv_s8 c2 = npyv_loada_s8(data_out + vstep * 2);
            
#line 390
            npyv_s8 a3 = npyv_loada_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_loada_s8(data1 + vstep * 3);
            npyv_s8 c3 = npyv_loada_s8(data_out + vstep * 3);
            
            #line 397
            npyv_s8 abc0 = npyv_muladd_s8(a0, b0, c0);
            
#line 397
            npyv_s8 abc1 = npyv_muladd_s8(a1, b1, c1);
            
#line 397
            npyv_s8 abc2 = npyv_muladd_s8(a2, b2, c2);
            
#line 397
            npyv_s8 abc3 = npyv_muladd_s8(a3, b3, c3);
            
            #line 402
            npyv_storea_s8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s8 a0 = npyv_load_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_load_s8(data1 + vstep * 0);
            npyv_s8 c0 = npyv_load_s8(data_out + vstep * 0);
            
#line 390
            npyv_s8 a1 = npyv_load_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_load_s8(data1 + vstep * 1);
            npyv_s8 c1 = npyv_load_s8(data_out + vstep * 1);
            
#line 390
            npyv_s8 a2 = npyv_load_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_load_s8(data1 + vstep * 2);
            npyv_s8 c2 = npyv_load_s8(data_out + vstep * 2);
            
#line 390
            npyv_s8 a3 = npyv_load_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_load_s8(data1 + vstep * 3);
            npyv_s8 c3 = npyv_load_s8(data_out + vstep * 3);
            
            #line 397
            npyv_s8 abc0 = npyv_muladd_s8(a0, b0, c0);
            
#line 397
            npyv_s8 abc1 = npyv_muladd_s8(a1, b1, c1);
            
#line 397
            npyv_s8 abc2 = npyv_muladd_s8(a2, b2, c2);
            
#line 397
            npyv_s8 abc3 = npyv_muladd_s8(a3, b3, c3);
            
            #line 402
            npyv_store_s8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data0, count);
        npyv_s8 b = npyv_load_tillz_s8(data1, count);
        npyv_s8 c = npyv_load_tillz_s8(data_out, count);
        npyv_store_till_s8(data_out, count, npyv_muladd_s8(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_byte a0 = (data0[0]);
        const npy_byte b0 = (data1[0]);
        const npy_byte c0 = (data_out[0]);
        
#line 420
        const npy_byte a1 = (data0[1]);
        const npy_byte b1 = (data1[1]);
        const npy_byte c1 = (data_out[1]);
        
#line 420
        const npy_byte a2 = (data0[2]);
        const npy_byte b2 = (data1[2]);
        const npy_byte c2 = (data_out[2]);
        
#line 420
        const npy_byte a3 = (data0[3]);
        const npy_byte b3 = (data1[3]);
        const npy_byte c3 = (data_out[3]);
        
        #line 427
        const npy_byte abc0 = a0 * b0 + c0;
        
#line 427
        const npy_byte abc1 = a1 * b1 + c1;
        
#line 427
        const npy_byte abc2 = a2 * b2 + c2;
        
#line 427
        const npy_byte abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_byte a = (*data0);
        const npy_byte b = (*data1);
        const npy_byte c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_byte

}

/* Some extra specializations for the two operand case */
static void
byte_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte value0 = (*(npy_byte *)dataptr[0]);
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data_out = (npy_byte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    byte_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
byte_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte value1 = (*(npy_byte *)dataptr[1]);
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data_out = (npy_byte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    byte_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte accum = 0;

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s8;
    npyv_s8 v_accum = npyv_zero_s8();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s8 a0 = npyv_loada_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_loada_s8(data1 + vstep * 0);
            
#line 501
            npyv_s8 a1 = npyv_loada_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_loada_s8(data1 + vstep * 1);
            
#line 501
            npyv_s8 a2 = npyv_loada_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_loada_s8(data1 + vstep * 2);
            
#line 501
            npyv_s8 a3 = npyv_loada_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_loada_s8(data1 + vstep * 3);
            
            npyv_s8 ab3 = npyv_muladd_s8(a3, b3, v_accum);
            npyv_s8 ab2 = npyv_muladd_s8(a2, b2, ab3);
            npyv_s8 ab1 = npyv_muladd_s8(a1, b1, ab2);
                   v_accum = npyv_muladd_s8(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s8 a0 = npyv_load_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_load_s8(data1 + vstep * 0);
            
#line 501
            npyv_s8 a1 = npyv_load_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_load_s8(data1 + vstep * 1);
            
#line 501
            npyv_s8 a2 = npyv_load_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_load_s8(data1 + vstep * 2);
            
#line 501
            npyv_s8 a3 = npyv_load_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_load_s8(data1 + vstep * 3);
            
            npyv_s8 ab3 = npyv_muladd_s8(a3, b3, v_accum);
            npyv_s8 ab2 = npyv_muladd_s8(a2, b2, ab3);
            npyv_s8 ab1 = npyv_muladd_s8(a1, b1, ab2);
                   v_accum = npyv_muladd_s8(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data0, count);
        npyv_s8 b = npyv_load_tillz_s8(data1, count);
        v_accum = npyv_muladd_s8(a, b, v_accum);
    }
    accum = npyv_sum_s8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_byte ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_byte ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_byte ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_byte ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_byte a = (*data0);
        const npy_byte b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_byte
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte value0 = (*(npy_byte *)dataptr[0]);
    npy_byte accum = byte_sum_of_arr(data1, count);
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte value1 = (*(npy_byte *)dataptr[1]);
    npy_byte accum = byte_sum_of_arr(data0, count);
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
byte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data2 = (npy_byte *)dataptr[2];
    npy_byte *data_out = (npy_byte *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
byte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        *(npy_byte *)dataptr[nop] = (temp +
                                           (*(npy_byte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_byte);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_byte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_byte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_byte);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_byte *data = (npy_byte *)dataptr[0];
    npy_byte accum = byte_sum_of_arr(data, count);
    *((npy_byte *)dataptr[1]) = (accum + (*((npy_byte *)dataptr[1])));
#else
    npy_byte accum_re = 0, accum_im = 0;
    npy_byte *data0 = (npy_byte *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_byte re01 = data0[0] + data0[2];
        const npy_byte re23 = data0[4] + data0[6];
        const npy_byte im13 = data0[1] + data0[3];
        const npy_byte im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_byte *)dataptr[1])[0] += accum_re;
    ((npy_byte *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
byte_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_byte accum_re = 0, accum_im = 0;
#else
    npy_byte accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_byte *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_byte *)data0) *
                 (*(npy_byte *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_byte *)data0) *
                 (*(npy_byte *)data1) *
                 (*(npy_byte *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_byte *)data0)[0];
        accum_im += ((npy_byte *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_byte *)dataptr[2])[0] += accum_re;
    ((npy_byte *)dataptr[2])[1] += accum_im;
#  else
    ((npy_byte *)dataptr[nop])[0] += accum_re;
    ((npy_byte *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_byte *)dataptr[2]) = (accum +
                                    (*((npy_byte *)dataptr[2])));
#  else
    *((npy_byte *)dataptr[nop]) = (accum +
                                    (*((npy_byte *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
byte_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_byte *)data_out = ((*(npy_byte *)data0) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_byte *)data_out = ((*(npy_byte *)data0) *
                                         (*(npy_byte *)data1) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_byte *)data_out = ((*(npy_byte *)data0) *
                                         (*(npy_byte *)data1) *
                                         (*(npy_byte *)data2) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        *(npy_byte *)dataptr[nop] = (temp +
                                           (*(npy_byte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_byte *)data_out)[0] = ((npy_byte *)data0)[0] +
                                         ((npy_byte *)data_out)[0];
        ((npy_byte *)data_out)[1] = ((npy_byte *)data0)[1] +
                                         ((npy_byte *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_byte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_byte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
byte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data_out = (npy_byte *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_byte *)data_out + 2*6)[0] =
                                    ((npy_byte *)data0 + 2*6)[0] +
                                    ((npy_byte *)data_out + 2*6)[0];
            ((npy_byte *)data_out + 2*6)[1] =
                                    ((npy_byte *)data0 + 2*6)[1] +
                                    ((npy_byte *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_byte *)data_out + 2*5)[0] =
                                    ((npy_byte *)data0 + 2*5)[0] +
                                    ((npy_byte *)data_out + 2*5)[0];
            ((npy_byte *)data_out + 2*5)[1] =
                                    ((npy_byte *)data0 + 2*5)[1] +
                                    ((npy_byte *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_byte *)data_out + 2*4)[0] =
                                    ((npy_byte *)data0 + 2*4)[0] +
                                    ((npy_byte *)data_out + 2*4)[0];
            ((npy_byte *)data_out + 2*4)[1] =
                                    ((npy_byte *)data0 + 2*4)[1] +
                                    ((npy_byte *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_byte *)data_out + 2*3)[0] =
                                    ((npy_byte *)data0 + 2*3)[0] +
                                    ((npy_byte *)data_out + 2*3)[0];
            ((npy_byte *)data_out + 2*3)[1] =
                                    ((npy_byte *)data0 + 2*3)[1] +
                                    ((npy_byte *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_byte *)data_out + 2*2)[0] =
                                    ((npy_byte *)data0 + 2*2)[0] +
                                    ((npy_byte *)data_out + 2*2)[0];
            ((npy_byte *)data_out + 2*2)[1] =
                                    ((npy_byte *)data0 + 2*2)[1] +
                                    ((npy_byte *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_byte *)data_out + 2*1)[0] =
                                    ((npy_byte *)data0 + 2*1)[0] +
                                    ((npy_byte *)data_out + 2*1)[0];
            ((npy_byte *)data_out + 2*1)[1] =
                                    ((npy_byte *)data0 + 2*1)[1] +
                                    ((npy_byte *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_byte *)data_out + 2*0)[0] =
                                    ((npy_byte *)data0 + 2*0)[0] +
                                    ((npy_byte *)data_out + 2*0)[0];
            ((npy_byte *)data_out + 2*0)[1] =
                                    ((npy_byte *)data0 + 2*0)[1] +
                                    ((npy_byte *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_byte *)data_out + 2*0)[0] =
                                ((npy_byte *)data0 + 2*0)[0] +
                                ((npy_byte *)data_out + 2*0)[0];
        ((npy_byte *)data_out + 2*0)[1] =
                                ((npy_byte *)data0 + 2*0)[1] +
                                ((npy_byte *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_byte *)data_out + 2*1)[0] =
                                ((npy_byte *)data0 + 2*1)[0] +
                                ((npy_byte *)data_out + 2*1)[0];
        ((npy_byte *)data_out + 2*1)[1] =
                                ((npy_byte *)data0 + 2*1)[1] +
                                ((npy_byte *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_byte *)data_out + 2*2)[0] =
                                ((npy_byte *)data0 + 2*2)[0] +
                                ((npy_byte *)data_out + 2*2)[0];
        ((npy_byte *)data_out + 2*2)[1] =
                                ((npy_byte *)data0 + 2*2)[1] +
                                ((npy_byte *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_byte *)data_out + 2*3)[0] =
                                ((npy_byte *)data0 + 2*3)[0] +
                                ((npy_byte *)data_out + 2*3)[0];
        ((npy_byte *)data_out + 2*3)[1] =
                                ((npy_byte *)data0 + 2*3)[1] +
                                ((npy_byte *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_byte *)data_out + 2*4)[0] =
                                ((npy_byte *)data0 + 2*4)[0] +
                                ((npy_byte *)data_out + 2*4)[0];
        ((npy_byte *)data_out + 2*4)[1] =
                                ((npy_byte *)data0 + 2*4)[1] +
                                ((npy_byte *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_byte *)data_out + 2*5)[0] =
                                ((npy_byte *)data0 + 2*5)[0] +
                                ((npy_byte *)data_out + 2*5)[0];
        ((npy_byte *)data_out + 2*5)[1] =
                                ((npy_byte *)data0 + 2*5)[1] +
                                ((npy_byte *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_byte *)data_out + 2*6)[0] =
                                ((npy_byte *)data0 + 2*6)[0] +
                                ((npy_byte *)data_out + 2*6)[0];
        ((npy_byte *)data_out + 2*6)[1] =
                                ((npy_byte *)data0 + 2*6)[1] +
                                ((npy_byte *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_byte *)data_out + 2*7)[0] =
                                ((npy_byte *)data0 + 2*7)[0] +
                                ((npy_byte *)data_out + 2*7)[0];
        ((npy_byte *)data_out + 2*7)[1] =
                                ((npy_byte *)data0 + 2*7)[1] +
                                ((npy_byte *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
byte_sum_of_products_muladd(npy_byte *data, npy_byte *data_out, npy_byte scalar, npy_intp count)
{
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s8;
    const npyv_s8 v_scalar = npyv_setall_s8(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s8 b0 = npyv_loada_s8(data + vstep * 0);
            npyv_s8 c0 = npyv_loada_s8(data_out + vstep * 0);
            
#line 312
            npyv_s8 b1 = npyv_loada_s8(data + vstep * 1);
            npyv_s8 c1 = npyv_loada_s8(data_out + vstep * 1);
            
#line 312
            npyv_s8 b2 = npyv_loada_s8(data + vstep * 2);
            npyv_s8 c2 = npyv_loada_s8(data_out + vstep * 2);
            
#line 312
            npyv_s8 b3 = npyv_loada_s8(data + vstep * 3);
            npyv_s8 c3 = npyv_loada_s8(data_out + vstep * 3);
            
            #line 318
            npyv_s8 abc0 = npyv_muladd_s8(v_scalar, b0, c0);
            
#line 318
            npyv_s8 abc1 = npyv_muladd_s8(v_scalar, b1, c1);
            
#line 318
            npyv_s8 abc2 = npyv_muladd_s8(v_scalar, b2, c2);
            
#line 318
            npyv_s8 abc3 = npyv_muladd_s8(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s8 b0 = npyv_load_s8(data + vstep * 0);
            npyv_s8 c0 = npyv_load_s8(data_out + vstep * 0);
            
#line 312
            npyv_s8 b1 = npyv_load_s8(data + vstep * 1);
            npyv_s8 c1 = npyv_load_s8(data_out + vstep * 1);
            
#line 312
            npyv_s8 b2 = npyv_load_s8(data + vstep * 2);
            npyv_s8 c2 = npyv_load_s8(data_out + vstep * 2);
            
#line 312
            npyv_s8 b3 = npyv_load_s8(data + vstep * 3);
            npyv_s8 c3 = npyv_load_s8(data_out + vstep * 3);
            
            #line 318
            npyv_s8 abc0 = npyv_muladd_s8(v_scalar, b0, c0);
            
#line 318
            npyv_s8 abc1 = npyv_muladd_s8(v_scalar, b1, c1);
            
#line 318
            npyv_s8 abc2 = npyv_muladd_s8(v_scalar, b2, c2);
            
#line 318
            npyv_s8 abc3 = npyv_muladd_s8(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data, count);
        npyv_s8 b = npyv_load_tillz_s8(data_out, count);
        npyv_store_till_s8(data_out, count, npyv_muladd_s8(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_byte b0 = (data[0]);
        const npy_byte c0 = (data_out[0]);
        
#line 340
        const npy_byte b1 = (data[1]);
        const npy_byte c1 = (data_out[1]);
        
#line 340
        const npy_byte b2 = (data[2]);
        const npy_byte c2 = (data_out[2]);
        
#line 340
        const npy_byte b3 = (data[3]);
        const npy_byte c3 = (data_out[3]);
        
        #line 346
        const npy_byte abc0 = scalar * b0 + c0;
        
#line 346
        const npy_byte abc1 = scalar * b1 + c1;
        
#line 346
        const npy_byte abc2 = scalar * b2 + c2;
        
#line 346
        const npy_byte abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_byte b = (*data);
        const npy_byte c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_byte
}

static void
byte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data_out = (npy_byte *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_byte
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s8;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s8 a0 = npyv_loada_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_loada_s8(data1 + vstep * 0);
            npyv_s8 c0 = npyv_loada_s8(data_out + vstep * 0);
            
#line 390
            npyv_s8 a1 = npyv_loada_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_loada_s8(data1 + vstep * 1);
            npyv_s8 c1 = npyv_loada_s8(data_out + vstep * 1);
            
#line 390
            npyv_s8 a2 = npyv_loada_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_loada_s8(data1 + vstep * 2);
            npyv_s8 c2 = npyv_loada_s8(data_out + vstep * 2);
            
#line 390
            npyv_s8 a3 = npyv_loada_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_loada_s8(data1 + vstep * 3);
            npyv_s8 c3 = npyv_loada_s8(data_out + vstep * 3);
            
            #line 397
            npyv_s8 abc0 = npyv_muladd_s8(a0, b0, c0);
            
#line 397
            npyv_s8 abc1 = npyv_muladd_s8(a1, b1, c1);
            
#line 397
            npyv_s8 abc2 = npyv_muladd_s8(a2, b2, c2);
            
#line 397
            npyv_s8 abc3 = npyv_muladd_s8(a3, b3, c3);
            
            #line 402
            npyv_storea_s8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s8 a0 = npyv_load_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_load_s8(data1 + vstep * 0);
            npyv_s8 c0 = npyv_load_s8(data_out + vstep * 0);
            
#line 390
            npyv_s8 a1 = npyv_load_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_load_s8(data1 + vstep * 1);
            npyv_s8 c1 = npyv_load_s8(data_out + vstep * 1);
            
#line 390
            npyv_s8 a2 = npyv_load_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_load_s8(data1 + vstep * 2);
            npyv_s8 c2 = npyv_load_s8(data_out + vstep * 2);
            
#line 390
            npyv_s8 a3 = npyv_load_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_load_s8(data1 + vstep * 3);
            npyv_s8 c3 = npyv_load_s8(data_out + vstep * 3);
            
            #line 397
            npyv_s8 abc0 = npyv_muladd_s8(a0, b0, c0);
            
#line 397
            npyv_s8 abc1 = npyv_muladd_s8(a1, b1, c1);
            
#line 397
            npyv_s8 abc2 = npyv_muladd_s8(a2, b2, c2);
            
#line 397
            npyv_s8 abc3 = npyv_muladd_s8(a3, b3, c3);
            
            #line 402
            npyv_store_s8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data0, count);
        npyv_s8 b = npyv_load_tillz_s8(data1, count);
        npyv_s8 c = npyv_load_tillz_s8(data_out, count);
        npyv_store_till_s8(data_out, count, npyv_muladd_s8(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_byte a0 = (data0[0]);
        const npy_byte b0 = (data1[0]);
        const npy_byte c0 = (data_out[0]);
        
#line 420
        const npy_byte a1 = (data0[1]);
        const npy_byte b1 = (data1[1]);
        const npy_byte c1 = (data_out[1]);
        
#line 420
        const npy_byte a2 = (data0[2]);
        const npy_byte b2 = (data1[2]);
        const npy_byte c2 = (data_out[2]);
        
#line 420
        const npy_byte a3 = (data0[3]);
        const npy_byte b3 = (data1[3]);
        const npy_byte c3 = (data_out[3]);
        
        #line 427
        const npy_byte abc0 = a0 * b0 + c0;
        
#line 427
        const npy_byte abc1 = a1 * b1 + c1;
        
#line 427
        const npy_byte abc2 = a2 * b2 + c2;
        
#line 427
        const npy_byte abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_byte a = (*data0);
        const npy_byte b = (*data1);
        const npy_byte c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_byte

}

/* Some extra specializations for the two operand case */
static void
byte_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte value0 = (*(npy_byte *)dataptr[0]);
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data_out = (npy_byte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    byte_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
byte_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte value1 = (*(npy_byte *)dataptr[1]);
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data_out = (npy_byte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    byte_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte accum = 0;

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s8;
    npyv_s8 v_accum = npyv_zero_s8();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s8 a0 = npyv_loada_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_loada_s8(data1 + vstep * 0);
            
#line 501
            npyv_s8 a1 = npyv_loada_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_loada_s8(data1 + vstep * 1);
            
#line 501
            npyv_s8 a2 = npyv_loada_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_loada_s8(data1 + vstep * 2);
            
#line 501
            npyv_s8 a3 = npyv_loada_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_loada_s8(data1 + vstep * 3);
            
            npyv_s8 ab3 = npyv_muladd_s8(a3, b3, v_accum);
            npyv_s8 ab2 = npyv_muladd_s8(a2, b2, ab3);
            npyv_s8 ab1 = npyv_muladd_s8(a1, b1, ab2);
                   v_accum = npyv_muladd_s8(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s8 a0 = npyv_load_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_load_s8(data1 + vstep * 0);
            
#line 501
            npyv_s8 a1 = npyv_load_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_load_s8(data1 + vstep * 1);
            
#line 501
            npyv_s8 a2 = npyv_load_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_load_s8(data1 + vstep * 2);
            
#line 501
            npyv_s8 a3 = npyv_load_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_load_s8(data1 + vstep * 3);
            
            npyv_s8 ab3 = npyv_muladd_s8(a3, b3, v_accum);
            npyv_s8 ab2 = npyv_muladd_s8(a2, b2, ab3);
            npyv_s8 ab1 = npyv_muladd_s8(a1, b1, ab2);
                   v_accum = npyv_muladd_s8(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data0, count);
        npyv_s8 b = npyv_load_tillz_s8(data1, count);
        v_accum = npyv_muladd_s8(a, b, v_accum);
    }
    accum = npyv_sum_s8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_byte ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_byte ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_byte ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_byte ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_byte a = (*data0);
        const npy_byte b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_byte
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte value0 = (*(npy_byte *)dataptr[0]);
    npy_byte accum = byte_sum_of_arr(data1, count);
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte value1 = (*(npy_byte *)dataptr[1]);
    npy_byte accum = byte_sum_of_arr(data0, count);
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
byte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data2 = (npy_byte *)dataptr[2];
    npy_byte *data_out = (npy_byte *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
byte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        *(npy_byte *)dataptr[nop] = (temp +
                                           (*(npy_byte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_byte);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_byte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_byte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_byte);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_byte *data = (npy_byte *)dataptr[0];
    npy_byte accum = byte_sum_of_arr(data, count);
    *((npy_byte *)dataptr[1]) = (accum + (*((npy_byte *)dataptr[1])));
#else
    npy_byte accum_re = 0, accum_im = 0;
    npy_byte *data0 = (npy_byte *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_byte re01 = data0[0] + data0[2];
        const npy_byte re23 = data0[4] + data0[6];
        const npy_byte im13 = data0[1] + data0[3];
        const npy_byte im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_byte *)dataptr[1])[0] += accum_re;
    ((npy_byte *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
byte_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_byte accum_re = 0, accum_im = 0;
#else
    npy_byte accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_byte *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_byte *)data0) *
                 (*(npy_byte *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_byte *)data0) *
                 (*(npy_byte *)data1) *
                 (*(npy_byte *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_byte *)data0)[0];
        accum_im += ((npy_byte *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_byte *)dataptr[3])[0] += accum_re;
    ((npy_byte *)dataptr[3])[1] += accum_im;
#  else
    ((npy_byte *)dataptr[nop])[0] += accum_re;
    ((npy_byte *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_byte *)dataptr[3]) = (accum +
                                    (*((npy_byte *)dataptr[3])));
#  else
    *((npy_byte *)dataptr[nop]) = (accum +
                                    (*((npy_byte *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
byte_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_byte *)data_out = ((*(npy_byte *)data0) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_byte *)data_out = ((*(npy_byte *)data0) *
                                         (*(npy_byte *)data1) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_byte *)data_out = ((*(npy_byte *)data0) *
                                         (*(npy_byte *)data1) *
                                         (*(npy_byte *)data2) +
                                         (*(npy_byte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        *(npy_byte *)dataptr[nop] = (temp +
                                           (*(npy_byte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_byte *)data_out)[0] = ((npy_byte *)data0)[0] +
                                         ((npy_byte *)data_out)[0];
        ((npy_byte *)data_out)[1] = ((npy_byte *)data0)[1] +
                                         ((npy_byte *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_byte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_byte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
byte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data_out = (npy_byte *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_byte *)data_out + 2*6)[0] =
                                    ((npy_byte *)data0 + 2*6)[0] +
                                    ((npy_byte *)data_out + 2*6)[0];
            ((npy_byte *)data_out + 2*6)[1] =
                                    ((npy_byte *)data0 + 2*6)[1] +
                                    ((npy_byte *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_byte *)data_out + 2*5)[0] =
                                    ((npy_byte *)data0 + 2*5)[0] +
                                    ((npy_byte *)data_out + 2*5)[0];
            ((npy_byte *)data_out + 2*5)[1] =
                                    ((npy_byte *)data0 + 2*5)[1] +
                                    ((npy_byte *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_byte *)data_out + 2*4)[0] =
                                    ((npy_byte *)data0 + 2*4)[0] +
                                    ((npy_byte *)data_out + 2*4)[0];
            ((npy_byte *)data_out + 2*4)[1] =
                                    ((npy_byte *)data0 + 2*4)[1] +
                                    ((npy_byte *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_byte *)data_out + 2*3)[0] =
                                    ((npy_byte *)data0 + 2*3)[0] +
                                    ((npy_byte *)data_out + 2*3)[0];
            ((npy_byte *)data_out + 2*3)[1] =
                                    ((npy_byte *)data0 + 2*3)[1] +
                                    ((npy_byte *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_byte *)data_out + 2*2)[0] =
                                    ((npy_byte *)data0 + 2*2)[0] +
                                    ((npy_byte *)data_out + 2*2)[0];
            ((npy_byte *)data_out + 2*2)[1] =
                                    ((npy_byte *)data0 + 2*2)[1] +
                                    ((npy_byte *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_byte *)data_out + 2*1)[0] =
                                    ((npy_byte *)data0 + 2*1)[0] +
                                    ((npy_byte *)data_out + 2*1)[0];
            ((npy_byte *)data_out + 2*1)[1] =
                                    ((npy_byte *)data0 + 2*1)[1] +
                                    ((npy_byte *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_byte *)data_out + 2*0)[0] =
                                    ((npy_byte *)data0 + 2*0)[0] +
                                    ((npy_byte *)data_out + 2*0)[0];
            ((npy_byte *)data_out + 2*0)[1] =
                                    ((npy_byte *)data0 + 2*0)[1] +
                                    ((npy_byte *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_byte *)data_out + 2*0)[0] =
                                ((npy_byte *)data0 + 2*0)[0] +
                                ((npy_byte *)data_out + 2*0)[0];
        ((npy_byte *)data_out + 2*0)[1] =
                                ((npy_byte *)data0 + 2*0)[1] +
                                ((npy_byte *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_byte *)data_out + 2*1)[0] =
                                ((npy_byte *)data0 + 2*1)[0] +
                                ((npy_byte *)data_out + 2*1)[0];
        ((npy_byte *)data_out + 2*1)[1] =
                                ((npy_byte *)data0 + 2*1)[1] +
                                ((npy_byte *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_byte *)data_out + 2*2)[0] =
                                ((npy_byte *)data0 + 2*2)[0] +
                                ((npy_byte *)data_out + 2*2)[0];
        ((npy_byte *)data_out + 2*2)[1] =
                                ((npy_byte *)data0 + 2*2)[1] +
                                ((npy_byte *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_byte *)data_out + 2*3)[0] =
                                ((npy_byte *)data0 + 2*3)[0] +
                                ((npy_byte *)data_out + 2*3)[0];
        ((npy_byte *)data_out + 2*3)[1] =
                                ((npy_byte *)data0 + 2*3)[1] +
                                ((npy_byte *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_byte *)data_out + 2*4)[0] =
                                ((npy_byte *)data0 + 2*4)[0] +
                                ((npy_byte *)data_out + 2*4)[0];
        ((npy_byte *)data_out + 2*4)[1] =
                                ((npy_byte *)data0 + 2*4)[1] +
                                ((npy_byte *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_byte *)data_out + 2*5)[0] =
                                ((npy_byte *)data0 + 2*5)[0] +
                                ((npy_byte *)data_out + 2*5)[0];
        ((npy_byte *)data_out + 2*5)[1] =
                                ((npy_byte *)data0 + 2*5)[1] +
                                ((npy_byte *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_byte *)data_out + 2*6)[0] =
                                ((npy_byte *)data0 + 2*6)[0] +
                                ((npy_byte *)data_out + 2*6)[0];
        ((npy_byte *)data_out + 2*6)[1] =
                                ((npy_byte *)data0 + 2*6)[1] +
                                ((npy_byte *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_byte *)data_out + 2*7)[0] =
                                ((npy_byte *)data0 + 2*7)[0] +
                                ((npy_byte *)data_out + 2*7)[0];
        ((npy_byte *)data_out + 2*7)[1] =
                                ((npy_byte *)data0 + 2*7)[1] +
                                ((npy_byte *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
byte_sum_of_products_muladd(npy_byte *data, npy_byte *data_out, npy_byte scalar, npy_intp count)
{
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s8;
    const npyv_s8 v_scalar = npyv_setall_s8(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s8 b0 = npyv_loada_s8(data + vstep * 0);
            npyv_s8 c0 = npyv_loada_s8(data_out + vstep * 0);
            
#line 312
            npyv_s8 b1 = npyv_loada_s8(data + vstep * 1);
            npyv_s8 c1 = npyv_loada_s8(data_out + vstep * 1);
            
#line 312
            npyv_s8 b2 = npyv_loada_s8(data + vstep * 2);
            npyv_s8 c2 = npyv_loada_s8(data_out + vstep * 2);
            
#line 312
            npyv_s8 b3 = npyv_loada_s8(data + vstep * 3);
            npyv_s8 c3 = npyv_loada_s8(data_out + vstep * 3);
            
            #line 318
            npyv_s8 abc0 = npyv_muladd_s8(v_scalar, b0, c0);
            
#line 318
            npyv_s8 abc1 = npyv_muladd_s8(v_scalar, b1, c1);
            
#line 318
            npyv_s8 abc2 = npyv_muladd_s8(v_scalar, b2, c2);
            
#line 318
            npyv_s8 abc3 = npyv_muladd_s8(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s8 b0 = npyv_load_s8(data + vstep * 0);
            npyv_s8 c0 = npyv_load_s8(data_out + vstep * 0);
            
#line 312
            npyv_s8 b1 = npyv_load_s8(data + vstep * 1);
            npyv_s8 c1 = npyv_load_s8(data_out + vstep * 1);
            
#line 312
            npyv_s8 b2 = npyv_load_s8(data + vstep * 2);
            npyv_s8 c2 = npyv_load_s8(data_out + vstep * 2);
            
#line 312
            npyv_s8 b3 = npyv_load_s8(data + vstep * 3);
            npyv_s8 c3 = npyv_load_s8(data_out + vstep * 3);
            
            #line 318
            npyv_s8 abc0 = npyv_muladd_s8(v_scalar, b0, c0);
            
#line 318
            npyv_s8 abc1 = npyv_muladd_s8(v_scalar, b1, c1);
            
#line 318
            npyv_s8 abc2 = npyv_muladd_s8(v_scalar, b2, c2);
            
#line 318
            npyv_s8 abc3 = npyv_muladd_s8(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data, count);
        npyv_s8 b = npyv_load_tillz_s8(data_out, count);
        npyv_store_till_s8(data_out, count, npyv_muladd_s8(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_byte b0 = (data[0]);
        const npy_byte c0 = (data_out[0]);
        
#line 340
        const npy_byte b1 = (data[1]);
        const npy_byte c1 = (data_out[1]);
        
#line 340
        const npy_byte b2 = (data[2]);
        const npy_byte c2 = (data_out[2]);
        
#line 340
        const npy_byte b3 = (data[3]);
        const npy_byte c3 = (data_out[3]);
        
        #line 346
        const npy_byte abc0 = scalar * b0 + c0;
        
#line 346
        const npy_byte abc1 = scalar * b1 + c1;
        
#line 346
        const npy_byte abc2 = scalar * b2 + c2;
        
#line 346
        const npy_byte abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_byte b = (*data);
        const npy_byte c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_byte
}

static void
byte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data_out = (npy_byte *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_byte
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s8;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s8 a0 = npyv_loada_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_loada_s8(data1 + vstep * 0);
            npyv_s8 c0 = npyv_loada_s8(data_out + vstep * 0);
            
#line 390
            npyv_s8 a1 = npyv_loada_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_loada_s8(data1 + vstep * 1);
            npyv_s8 c1 = npyv_loada_s8(data_out + vstep * 1);
            
#line 390
            npyv_s8 a2 = npyv_loada_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_loada_s8(data1 + vstep * 2);
            npyv_s8 c2 = npyv_loada_s8(data_out + vstep * 2);
            
#line 390
            npyv_s8 a3 = npyv_loada_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_loada_s8(data1 + vstep * 3);
            npyv_s8 c3 = npyv_loada_s8(data_out + vstep * 3);
            
            #line 397
            npyv_s8 abc0 = npyv_muladd_s8(a0, b0, c0);
            
#line 397
            npyv_s8 abc1 = npyv_muladd_s8(a1, b1, c1);
            
#line 397
            npyv_s8 abc2 = npyv_muladd_s8(a2, b2, c2);
            
#line 397
            npyv_s8 abc3 = npyv_muladd_s8(a3, b3, c3);
            
            #line 402
            npyv_storea_s8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s8 a0 = npyv_load_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_load_s8(data1 + vstep * 0);
            npyv_s8 c0 = npyv_load_s8(data_out + vstep * 0);
            
#line 390
            npyv_s8 a1 = npyv_load_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_load_s8(data1 + vstep * 1);
            npyv_s8 c1 = npyv_load_s8(data_out + vstep * 1);
            
#line 390
            npyv_s8 a2 = npyv_load_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_load_s8(data1 + vstep * 2);
            npyv_s8 c2 = npyv_load_s8(data_out + vstep * 2);
            
#line 390
            npyv_s8 a3 = npyv_load_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_load_s8(data1 + vstep * 3);
            npyv_s8 c3 = npyv_load_s8(data_out + vstep * 3);
            
            #line 397
            npyv_s8 abc0 = npyv_muladd_s8(a0, b0, c0);
            
#line 397
            npyv_s8 abc1 = npyv_muladd_s8(a1, b1, c1);
            
#line 397
            npyv_s8 abc2 = npyv_muladd_s8(a2, b2, c2);
            
#line 397
            npyv_s8 abc3 = npyv_muladd_s8(a3, b3, c3);
            
            #line 402
            npyv_store_s8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data0, count);
        npyv_s8 b = npyv_load_tillz_s8(data1, count);
        npyv_s8 c = npyv_load_tillz_s8(data_out, count);
        npyv_store_till_s8(data_out, count, npyv_muladd_s8(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_byte a0 = (data0[0]);
        const npy_byte b0 = (data1[0]);
        const npy_byte c0 = (data_out[0]);
        
#line 420
        const npy_byte a1 = (data0[1]);
        const npy_byte b1 = (data1[1]);
        const npy_byte c1 = (data_out[1]);
        
#line 420
        const npy_byte a2 = (data0[2]);
        const npy_byte b2 = (data1[2]);
        const npy_byte c2 = (data_out[2]);
        
#line 420
        const npy_byte a3 = (data0[3]);
        const npy_byte b3 = (data1[3]);
        const npy_byte c3 = (data_out[3]);
        
        #line 427
        const npy_byte abc0 = a0 * b0 + c0;
        
#line 427
        const npy_byte abc1 = a1 * b1 + c1;
        
#line 427
        const npy_byte abc2 = a2 * b2 + c2;
        
#line 427
        const npy_byte abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_byte a = (*data0);
        const npy_byte b = (*data1);
        const npy_byte c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_byte

}

/* Some extra specializations for the two operand case */
static void
byte_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte value0 = (*(npy_byte *)dataptr[0]);
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data_out = (npy_byte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    byte_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
byte_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte value1 = (*(npy_byte *)dataptr[1]);
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data_out = (npy_byte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    byte_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte accum = 0;

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_byte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s8;
    npyv_s8 v_accum = npyv_zero_s8();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s8 a0 = npyv_loada_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_loada_s8(data1 + vstep * 0);
            
#line 501
            npyv_s8 a1 = npyv_loada_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_loada_s8(data1 + vstep * 1);
            
#line 501
            npyv_s8 a2 = npyv_loada_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_loada_s8(data1 + vstep * 2);
            
#line 501
            npyv_s8 a3 = npyv_loada_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_loada_s8(data1 + vstep * 3);
            
            npyv_s8 ab3 = npyv_muladd_s8(a3, b3, v_accum);
            npyv_s8 ab2 = npyv_muladd_s8(a2, b2, ab3);
            npyv_s8 ab1 = npyv_muladd_s8(a1, b1, ab2);
                   v_accum = npyv_muladd_s8(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s8 a0 = npyv_load_s8(data0 + vstep * 0);
            npyv_s8 b0 = npyv_load_s8(data1 + vstep * 0);
            
#line 501
            npyv_s8 a1 = npyv_load_s8(data0 + vstep * 1);
            npyv_s8 b1 = npyv_load_s8(data1 + vstep * 1);
            
#line 501
            npyv_s8 a2 = npyv_load_s8(data0 + vstep * 2);
            npyv_s8 b2 = npyv_load_s8(data1 + vstep * 2);
            
#line 501
            npyv_s8 a3 = npyv_load_s8(data0 + vstep * 3);
            npyv_s8 b3 = npyv_load_s8(data1 + vstep * 3);
            
            npyv_s8 ab3 = npyv_muladd_s8(a3, b3, v_accum);
            npyv_s8 ab2 = npyv_muladd_s8(a2, b2, ab3);
            npyv_s8 ab1 = npyv_muladd_s8(a1, b1, ab2);
                   v_accum = npyv_muladd_s8(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s8 a = npyv_load_tillz_s8(data0, count);
        npyv_s8 b = npyv_load_tillz_s8(data1, count);
        v_accum = npyv_muladd_s8(a, b, v_accum);
    }
    accum = npyv_sum_s8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_byte ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_byte ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_byte ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_byte ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_byte a = (*data0);
        const npy_byte b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_byte
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte value0 = (*(npy_byte *)dataptr[0]);
    npy_byte accum = byte_sum_of_arr(data1, count);
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte value1 = (*(npy_byte *)dataptr[1]);
    npy_byte accum = byte_sum_of_arr(data0, count);
    *(npy_byte *)dataptr[2] = ((*(npy_byte *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
byte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_byte *data0 = (npy_byte *)dataptr[0];
    npy_byte *data1 = (npy_byte *)dataptr[1];
    npy_byte *data2 = (npy_byte *)dataptr[2];
    npy_byte *data_out = (npy_byte *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
byte_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        *(npy_byte *)dataptr[nop] = (temp +
                                           (*(npy_byte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_byte);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_byte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_byte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_byte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_byte);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
byte_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_byte *data = (npy_byte *)dataptr[0];
    npy_byte accum = byte_sum_of_arr(data, count);
    *((npy_byte *)dataptr[1]) = (accum + (*((npy_byte *)dataptr[1])));
#else
    npy_byte accum_re = 0, accum_im = 0;
    npy_byte *data0 = (npy_byte *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_byte re01 = data0[0] + data0[2];
        const npy_byte re23 = data0[4] + data0[6];
        const npy_byte im13 = data0[1] + data0[3];
        const npy_byte im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_byte *)dataptr[1])[0] += accum_re;
    ((npy_byte *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
byte_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_byte accum_re = 0, accum_im = 0;
#else
    npy_byte accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("byte_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_byte *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_byte *)data0) *
                 (*(npy_byte *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_byte *)data0) *
                 (*(npy_byte *)data1) *
                 (*(npy_byte *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_byte temp = (*(npy_byte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_byte *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_byte *)data0)[0];
        accum_im += ((npy_byte *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_byte re, im, tmp;
        int i;
        re = ((npy_byte *)dataptr[0])[0];
        im = ((npy_byte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_byte *)dataptr[i])[0] -
                  im * ((npy_byte *)dataptr[i])[1];
            im = re * ((npy_byte *)dataptr[i])[1] +
                 im * ((npy_byte *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_byte *)dataptr[1000])[0] += accum_re;
    ((npy_byte *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_byte *)dataptr[nop])[0] += accum_re;
    ((npy_byte *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_byte *)dataptr[1000]) = (accum +
                                    (*((npy_byte *)dataptr[1000])));
#  else
    *((npy_byte *)dataptr[nop]) = (accum +
                                    (*((npy_byte *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_short short_sum_of_arr(npy_short *data, npy_intp count)
{
    npy_short accum = 0;
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_s16;
    npyv_s16 v_accum = npyv_zero_s16();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_s16 a0 = npyv_loada_s16(data + vstep * 0);
            
#line 96
            npyv_s16 a1 = npyv_loada_s16(data + vstep * 1);
            
#line 96
            npyv_s16 a2 = npyv_loada_s16(data + vstep * 2);
            
#line 96
            npyv_s16 a3 = npyv_loada_s16(data + vstep * 3);
            
            npyv_s16 a01   = npyv_add_s16(a0, a1);
            npyv_s16 a23   = npyv_add_s16(a2, a3);
            npyv_s16 a0123 = npyv_add_s16(a01, a23);
                     v_accum = npyv_add_s16(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_s16 a0 = npyv_load_s16(data + vstep * 0);
            
#line 96
            npyv_s16 a1 = npyv_load_s16(data + vstep * 1);
            
#line 96
            npyv_s16 a2 = npyv_load_s16(data + vstep * 2);
            
#line 96
            npyv_s16 a3 = npyv_load_s16(data + vstep * 3);
            
            npyv_s16 a01   = npyv_add_s16(a0, a1);
            npyv_s16 a23   = npyv_add_s16(a2, a3);
            npyv_s16 a0123 = npyv_add_s16(a01, a23);
                     v_accum = npyv_add_s16(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data, count);
        v_accum = npyv_add_s16(a, v_accum);
    }
    accum = npyv_sum_s16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_short a01 = (*data) + (data[1]);
        const npy_short a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_short
    return accum;
}
#endif

#line 131
static void
short_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_short *)data_out = ((*(npy_short *)data0) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_short *)data_out = ((*(npy_short *)data0) *
                                         (*(npy_short *)data1) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_short *)data_out = ((*(npy_short *)data0) *
                                         (*(npy_short *)data1) *
                                         (*(npy_short *)data2) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        *(npy_short *)dataptr[nop] = (temp +
                                           (*(npy_short *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_short *)data_out)[0] = ((npy_short *)data0)[0] +
                                         ((npy_short *)data_out)[0];
        ((npy_short *)data_out)[1] = ((npy_short *)data0)[1] +
                                         ((npy_short *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_short *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[0];
        ((npy_short *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
short_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data_out = (npy_short *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_short *)data_out + 2*6)[0] =
                                    ((npy_short *)data0 + 2*6)[0] +
                                    ((npy_short *)data_out + 2*6)[0];
            ((npy_short *)data_out + 2*6)[1] =
                                    ((npy_short *)data0 + 2*6)[1] +
                                    ((npy_short *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_short *)data_out + 2*5)[0] =
                                    ((npy_short *)data0 + 2*5)[0] +
                                    ((npy_short *)data_out + 2*5)[0];
            ((npy_short *)data_out + 2*5)[1] =
                                    ((npy_short *)data0 + 2*5)[1] +
                                    ((npy_short *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_short *)data_out + 2*4)[0] =
                                    ((npy_short *)data0 + 2*4)[0] +
                                    ((npy_short *)data_out + 2*4)[0];
            ((npy_short *)data_out + 2*4)[1] =
                                    ((npy_short *)data0 + 2*4)[1] +
                                    ((npy_short *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_short *)data_out + 2*3)[0] =
                                    ((npy_short *)data0 + 2*3)[0] +
                                    ((npy_short *)data_out + 2*3)[0];
            ((npy_short *)data_out + 2*3)[1] =
                                    ((npy_short *)data0 + 2*3)[1] +
                                    ((npy_short *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_short *)data_out + 2*2)[0] =
                                    ((npy_short *)data0 + 2*2)[0] +
                                    ((npy_short *)data_out + 2*2)[0];
            ((npy_short *)data_out + 2*2)[1] =
                                    ((npy_short *)data0 + 2*2)[1] +
                                    ((npy_short *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_short *)data_out + 2*1)[0] =
                                    ((npy_short *)data0 + 2*1)[0] +
                                    ((npy_short *)data_out + 2*1)[0];
            ((npy_short *)data_out + 2*1)[1] =
                                    ((npy_short *)data0 + 2*1)[1] +
                                    ((npy_short *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_short *)data_out + 2*0)[0] =
                                    ((npy_short *)data0 + 2*0)[0] +
                                    ((npy_short *)data_out + 2*0)[0];
            ((npy_short *)data_out + 2*0)[1] =
                                    ((npy_short *)data0 + 2*0)[1] +
                                    ((npy_short *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_short *)data_out + 2*0)[0] =
                                ((npy_short *)data0 + 2*0)[0] +
                                ((npy_short *)data_out + 2*0)[0];
        ((npy_short *)data_out + 2*0)[1] =
                                ((npy_short *)data0 + 2*0)[1] +
                                ((npy_short *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_short *)data_out + 2*1)[0] =
                                ((npy_short *)data0 + 2*1)[0] +
                                ((npy_short *)data_out + 2*1)[0];
        ((npy_short *)data_out + 2*1)[1] =
                                ((npy_short *)data0 + 2*1)[1] +
                                ((npy_short *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_short *)data_out + 2*2)[0] =
                                ((npy_short *)data0 + 2*2)[0] +
                                ((npy_short *)data_out + 2*2)[0];
        ((npy_short *)data_out + 2*2)[1] =
                                ((npy_short *)data0 + 2*2)[1] +
                                ((npy_short *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_short *)data_out + 2*3)[0] =
                                ((npy_short *)data0 + 2*3)[0] +
                                ((npy_short *)data_out + 2*3)[0];
        ((npy_short *)data_out + 2*3)[1] =
                                ((npy_short *)data0 + 2*3)[1] +
                                ((npy_short *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_short *)data_out + 2*4)[0] =
                                ((npy_short *)data0 + 2*4)[0] +
                                ((npy_short *)data_out + 2*4)[0];
        ((npy_short *)data_out + 2*4)[1] =
                                ((npy_short *)data0 + 2*4)[1] +
                                ((npy_short *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_short *)data_out + 2*5)[0] =
                                ((npy_short *)data0 + 2*5)[0] +
                                ((npy_short *)data_out + 2*5)[0];
        ((npy_short *)data_out + 2*5)[1] =
                                ((npy_short *)data0 + 2*5)[1] +
                                ((npy_short *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_short *)data_out + 2*6)[0] =
                                ((npy_short *)data0 + 2*6)[0] +
                                ((npy_short *)data_out + 2*6)[0];
        ((npy_short *)data_out + 2*6)[1] =
                                ((npy_short *)data0 + 2*6)[1] +
                                ((npy_short *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_short *)data_out + 2*7)[0] =
                                ((npy_short *)data0 + 2*7)[0] +
                                ((npy_short *)data_out + 2*7)[0];
        ((npy_short *)data_out + 2*7)[1] =
                                ((npy_short *)data0 + 2*7)[1] +
                                ((npy_short *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
short_sum_of_products_muladd(npy_short *data, npy_short *data_out, npy_short scalar, npy_intp count)
{
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s16;
    const npyv_s16 v_scalar = npyv_setall_s16(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s16 b0 = npyv_loada_s16(data + vstep * 0);
            npyv_s16 c0 = npyv_loada_s16(data_out + vstep * 0);
            
#line 312
            npyv_s16 b1 = npyv_loada_s16(data + vstep * 1);
            npyv_s16 c1 = npyv_loada_s16(data_out + vstep * 1);
            
#line 312
            npyv_s16 b2 = npyv_loada_s16(data + vstep * 2);
            npyv_s16 c2 = npyv_loada_s16(data_out + vstep * 2);
            
#line 312
            npyv_s16 b3 = npyv_loada_s16(data + vstep * 3);
            npyv_s16 c3 = npyv_loada_s16(data_out + vstep * 3);
            
            #line 318
            npyv_s16 abc0 = npyv_muladd_s16(v_scalar, b0, c0);
            
#line 318
            npyv_s16 abc1 = npyv_muladd_s16(v_scalar, b1, c1);
            
#line 318
            npyv_s16 abc2 = npyv_muladd_s16(v_scalar, b2, c2);
            
#line 318
            npyv_s16 abc3 = npyv_muladd_s16(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s16 b0 = npyv_load_s16(data + vstep * 0);
            npyv_s16 c0 = npyv_load_s16(data_out + vstep * 0);
            
#line 312
            npyv_s16 b1 = npyv_load_s16(data + vstep * 1);
            npyv_s16 c1 = npyv_load_s16(data_out + vstep * 1);
            
#line 312
            npyv_s16 b2 = npyv_load_s16(data + vstep * 2);
            npyv_s16 c2 = npyv_load_s16(data_out + vstep * 2);
            
#line 312
            npyv_s16 b3 = npyv_load_s16(data + vstep * 3);
            npyv_s16 c3 = npyv_load_s16(data_out + vstep * 3);
            
            #line 318
            npyv_s16 abc0 = npyv_muladd_s16(v_scalar, b0, c0);
            
#line 318
            npyv_s16 abc1 = npyv_muladd_s16(v_scalar, b1, c1);
            
#line 318
            npyv_s16 abc2 = npyv_muladd_s16(v_scalar, b2, c2);
            
#line 318
            npyv_s16 abc3 = npyv_muladd_s16(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data, count);
        npyv_s16 b = npyv_load_tillz_s16(data_out, count);
        npyv_store_till_s16(data_out, count, npyv_muladd_s16(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_short b0 = (data[0]);
        const npy_short c0 = (data_out[0]);
        
#line 340
        const npy_short b1 = (data[1]);
        const npy_short c1 = (data_out[1]);
        
#line 340
        const npy_short b2 = (data[2]);
        const npy_short c2 = (data_out[2]);
        
#line 340
        const npy_short b3 = (data[3]);
        const npy_short c3 = (data_out[3]);
        
        #line 346
        const npy_short abc0 = scalar * b0 + c0;
        
#line 346
        const npy_short abc1 = scalar * b1 + c1;
        
#line 346
        const npy_short abc2 = scalar * b2 + c2;
        
#line 346
        const npy_short abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_short b = (*data);
        const npy_short c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_short
}

static void
short_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data_out = (npy_short *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_short
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s16;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s16 a0 = npyv_loada_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_loada_s16(data1 + vstep * 0);
            npyv_s16 c0 = npyv_loada_s16(data_out + vstep * 0);
            
#line 390
            npyv_s16 a1 = npyv_loada_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_loada_s16(data1 + vstep * 1);
            npyv_s16 c1 = npyv_loada_s16(data_out + vstep * 1);
            
#line 390
            npyv_s16 a2 = npyv_loada_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_loada_s16(data1 + vstep * 2);
            npyv_s16 c2 = npyv_loada_s16(data_out + vstep * 2);
            
#line 390
            npyv_s16 a3 = npyv_loada_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_loada_s16(data1 + vstep * 3);
            npyv_s16 c3 = npyv_loada_s16(data_out + vstep * 3);
            
            #line 397
            npyv_s16 abc0 = npyv_muladd_s16(a0, b0, c0);
            
#line 397
            npyv_s16 abc1 = npyv_muladd_s16(a1, b1, c1);
            
#line 397
            npyv_s16 abc2 = npyv_muladd_s16(a2, b2, c2);
            
#line 397
            npyv_s16 abc3 = npyv_muladd_s16(a3, b3, c3);
            
            #line 402
            npyv_storea_s16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s16 a0 = npyv_load_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_load_s16(data1 + vstep * 0);
            npyv_s16 c0 = npyv_load_s16(data_out + vstep * 0);
            
#line 390
            npyv_s16 a1 = npyv_load_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_load_s16(data1 + vstep * 1);
            npyv_s16 c1 = npyv_load_s16(data_out + vstep * 1);
            
#line 390
            npyv_s16 a2 = npyv_load_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_load_s16(data1 + vstep * 2);
            npyv_s16 c2 = npyv_load_s16(data_out + vstep * 2);
            
#line 390
            npyv_s16 a3 = npyv_load_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_load_s16(data1 + vstep * 3);
            npyv_s16 c3 = npyv_load_s16(data_out + vstep * 3);
            
            #line 397
            npyv_s16 abc0 = npyv_muladd_s16(a0, b0, c0);
            
#line 397
            npyv_s16 abc1 = npyv_muladd_s16(a1, b1, c1);
            
#line 397
            npyv_s16 abc2 = npyv_muladd_s16(a2, b2, c2);
            
#line 397
            npyv_s16 abc3 = npyv_muladd_s16(a3, b3, c3);
            
            #line 402
            npyv_store_s16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data0, count);
        npyv_s16 b = npyv_load_tillz_s16(data1, count);
        npyv_s16 c = npyv_load_tillz_s16(data_out, count);
        npyv_store_till_s16(data_out, count, npyv_muladd_s16(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_short a0 = (data0[0]);
        const npy_short b0 = (data1[0]);
        const npy_short c0 = (data_out[0]);
        
#line 420
        const npy_short a1 = (data0[1]);
        const npy_short b1 = (data1[1]);
        const npy_short c1 = (data_out[1]);
        
#line 420
        const npy_short a2 = (data0[2]);
        const npy_short b2 = (data1[2]);
        const npy_short c2 = (data_out[2]);
        
#line 420
        const npy_short a3 = (data0[3]);
        const npy_short b3 = (data1[3]);
        const npy_short c3 = (data_out[3]);
        
        #line 427
        const npy_short abc0 = a0 * b0 + c0;
        
#line 427
        const npy_short abc1 = a1 * b1 + c1;
        
#line 427
        const npy_short abc2 = a2 * b2 + c2;
        
#line 427
        const npy_short abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_short a = (*data0);
        const npy_short b = (*data1);
        const npy_short c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_short

}

/* Some extra specializations for the two operand case */
static void
short_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short value0 = (*(npy_short *)dataptr[0]);
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data_out = (npy_short *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    short_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
short_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short value1 = (*(npy_short *)dataptr[1]);
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data_out = (npy_short *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    short_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short accum = 0;

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s16;
    npyv_s16 v_accum = npyv_zero_s16();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s16 a0 = npyv_loada_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_loada_s16(data1 + vstep * 0);
            
#line 501
            npyv_s16 a1 = npyv_loada_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_loada_s16(data1 + vstep * 1);
            
#line 501
            npyv_s16 a2 = npyv_loada_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_loada_s16(data1 + vstep * 2);
            
#line 501
            npyv_s16 a3 = npyv_loada_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_loada_s16(data1 + vstep * 3);
            
            npyv_s16 ab3 = npyv_muladd_s16(a3, b3, v_accum);
            npyv_s16 ab2 = npyv_muladd_s16(a2, b2, ab3);
            npyv_s16 ab1 = npyv_muladd_s16(a1, b1, ab2);
                   v_accum = npyv_muladd_s16(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s16 a0 = npyv_load_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_load_s16(data1 + vstep * 0);
            
#line 501
            npyv_s16 a1 = npyv_load_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_load_s16(data1 + vstep * 1);
            
#line 501
            npyv_s16 a2 = npyv_load_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_load_s16(data1 + vstep * 2);
            
#line 501
            npyv_s16 a3 = npyv_load_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_load_s16(data1 + vstep * 3);
            
            npyv_s16 ab3 = npyv_muladd_s16(a3, b3, v_accum);
            npyv_s16 ab2 = npyv_muladd_s16(a2, b2, ab3);
            npyv_s16 ab1 = npyv_muladd_s16(a1, b1, ab2);
                   v_accum = npyv_muladd_s16(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data0, count);
        npyv_s16 b = npyv_load_tillz_s16(data1, count);
        v_accum = npyv_muladd_s16(a, b, v_accum);
    }
    accum = npyv_sum_s16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_short ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_short ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_short ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_short ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_short a = (*data0);
        const npy_short b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_short
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short value0 = (*(npy_short *)dataptr[0]);
    npy_short accum = short_sum_of_arr(data1, count);
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short value1 = (*(npy_short *)dataptr[1]);
    npy_short accum = short_sum_of_arr(data0, count);
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
short_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data2 = (npy_short *)dataptr[2];
    npy_short *data_out = (npy_short *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
short_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        *(npy_short *)dataptr[nop] = (temp +
                                           (*(npy_short *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_short);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_short *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[0];
        ((npy_short *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_short);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_short *data = (npy_short *)dataptr[0];
    npy_short accum = short_sum_of_arr(data, count);
    *((npy_short *)dataptr[1]) = (accum + (*((npy_short *)dataptr[1])));
#else
    npy_short accum_re = 0, accum_im = 0;
    npy_short *data0 = (npy_short *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_short re01 = data0[0] + data0[2];
        const npy_short re23 = data0[4] + data0[6];
        const npy_short im13 = data0[1] + data0[3];
        const npy_short im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_short *)dataptr[1])[0] += accum_re;
    ((npy_short *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
short_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_short accum_re = 0, accum_im = 0;
#else
    npy_short accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_short *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_short *)data0) *
                 (*(npy_short *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_short *)data0) *
                 (*(npy_short *)data1) *
                 (*(npy_short *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_short *)data0)[0];
        accum_im += ((npy_short *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_short *)dataptr[1])[0] += accum_re;
    ((npy_short *)dataptr[1])[1] += accum_im;
#  else
    ((npy_short *)dataptr[nop])[0] += accum_re;
    ((npy_short *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_short *)dataptr[1]) = (accum +
                                    (*((npy_short *)dataptr[1])));
#  else
    *((npy_short *)dataptr[nop]) = (accum +
                                    (*((npy_short *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
short_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_short *)data_out = ((*(npy_short *)data0) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_short *)data_out = ((*(npy_short *)data0) *
                                         (*(npy_short *)data1) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_short *)data_out = ((*(npy_short *)data0) *
                                         (*(npy_short *)data1) *
                                         (*(npy_short *)data2) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        *(npy_short *)dataptr[nop] = (temp +
                                           (*(npy_short *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_short *)data_out)[0] = ((npy_short *)data0)[0] +
                                         ((npy_short *)data_out)[0];
        ((npy_short *)data_out)[1] = ((npy_short *)data0)[1] +
                                         ((npy_short *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_short *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[0];
        ((npy_short *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
short_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data_out = (npy_short *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_short *)data_out + 2*6)[0] =
                                    ((npy_short *)data0 + 2*6)[0] +
                                    ((npy_short *)data_out + 2*6)[0];
            ((npy_short *)data_out + 2*6)[1] =
                                    ((npy_short *)data0 + 2*6)[1] +
                                    ((npy_short *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_short *)data_out + 2*5)[0] =
                                    ((npy_short *)data0 + 2*5)[0] +
                                    ((npy_short *)data_out + 2*5)[0];
            ((npy_short *)data_out + 2*5)[1] =
                                    ((npy_short *)data0 + 2*5)[1] +
                                    ((npy_short *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_short *)data_out + 2*4)[0] =
                                    ((npy_short *)data0 + 2*4)[0] +
                                    ((npy_short *)data_out + 2*4)[0];
            ((npy_short *)data_out + 2*4)[1] =
                                    ((npy_short *)data0 + 2*4)[1] +
                                    ((npy_short *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_short *)data_out + 2*3)[0] =
                                    ((npy_short *)data0 + 2*3)[0] +
                                    ((npy_short *)data_out + 2*3)[0];
            ((npy_short *)data_out + 2*3)[1] =
                                    ((npy_short *)data0 + 2*3)[1] +
                                    ((npy_short *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_short *)data_out + 2*2)[0] =
                                    ((npy_short *)data0 + 2*2)[0] +
                                    ((npy_short *)data_out + 2*2)[0];
            ((npy_short *)data_out + 2*2)[1] =
                                    ((npy_short *)data0 + 2*2)[1] +
                                    ((npy_short *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_short *)data_out + 2*1)[0] =
                                    ((npy_short *)data0 + 2*1)[0] +
                                    ((npy_short *)data_out + 2*1)[0];
            ((npy_short *)data_out + 2*1)[1] =
                                    ((npy_short *)data0 + 2*1)[1] +
                                    ((npy_short *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_short *)data_out + 2*0)[0] =
                                    ((npy_short *)data0 + 2*0)[0] +
                                    ((npy_short *)data_out + 2*0)[0];
            ((npy_short *)data_out + 2*0)[1] =
                                    ((npy_short *)data0 + 2*0)[1] +
                                    ((npy_short *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_short *)data_out + 2*0)[0] =
                                ((npy_short *)data0 + 2*0)[0] +
                                ((npy_short *)data_out + 2*0)[0];
        ((npy_short *)data_out + 2*0)[1] =
                                ((npy_short *)data0 + 2*0)[1] +
                                ((npy_short *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_short *)data_out + 2*1)[0] =
                                ((npy_short *)data0 + 2*1)[0] +
                                ((npy_short *)data_out + 2*1)[0];
        ((npy_short *)data_out + 2*1)[1] =
                                ((npy_short *)data0 + 2*1)[1] +
                                ((npy_short *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_short *)data_out + 2*2)[0] =
                                ((npy_short *)data0 + 2*2)[0] +
                                ((npy_short *)data_out + 2*2)[0];
        ((npy_short *)data_out + 2*2)[1] =
                                ((npy_short *)data0 + 2*2)[1] +
                                ((npy_short *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_short *)data_out + 2*3)[0] =
                                ((npy_short *)data0 + 2*3)[0] +
                                ((npy_short *)data_out + 2*3)[0];
        ((npy_short *)data_out + 2*3)[1] =
                                ((npy_short *)data0 + 2*3)[1] +
                                ((npy_short *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_short *)data_out + 2*4)[0] =
                                ((npy_short *)data0 + 2*4)[0] +
                                ((npy_short *)data_out + 2*4)[0];
        ((npy_short *)data_out + 2*4)[1] =
                                ((npy_short *)data0 + 2*4)[1] +
                                ((npy_short *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_short *)data_out + 2*5)[0] =
                                ((npy_short *)data0 + 2*5)[0] +
                                ((npy_short *)data_out + 2*5)[0];
        ((npy_short *)data_out + 2*5)[1] =
                                ((npy_short *)data0 + 2*5)[1] +
                                ((npy_short *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_short *)data_out + 2*6)[0] =
                                ((npy_short *)data0 + 2*6)[0] +
                                ((npy_short *)data_out + 2*6)[0];
        ((npy_short *)data_out + 2*6)[1] =
                                ((npy_short *)data0 + 2*6)[1] +
                                ((npy_short *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_short *)data_out + 2*7)[0] =
                                ((npy_short *)data0 + 2*7)[0] +
                                ((npy_short *)data_out + 2*7)[0];
        ((npy_short *)data_out + 2*7)[1] =
                                ((npy_short *)data0 + 2*7)[1] +
                                ((npy_short *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
short_sum_of_products_muladd(npy_short *data, npy_short *data_out, npy_short scalar, npy_intp count)
{
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s16;
    const npyv_s16 v_scalar = npyv_setall_s16(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s16 b0 = npyv_loada_s16(data + vstep * 0);
            npyv_s16 c0 = npyv_loada_s16(data_out + vstep * 0);
            
#line 312
            npyv_s16 b1 = npyv_loada_s16(data + vstep * 1);
            npyv_s16 c1 = npyv_loada_s16(data_out + vstep * 1);
            
#line 312
            npyv_s16 b2 = npyv_loada_s16(data + vstep * 2);
            npyv_s16 c2 = npyv_loada_s16(data_out + vstep * 2);
            
#line 312
            npyv_s16 b3 = npyv_loada_s16(data + vstep * 3);
            npyv_s16 c3 = npyv_loada_s16(data_out + vstep * 3);
            
            #line 318
            npyv_s16 abc0 = npyv_muladd_s16(v_scalar, b0, c0);
            
#line 318
            npyv_s16 abc1 = npyv_muladd_s16(v_scalar, b1, c1);
            
#line 318
            npyv_s16 abc2 = npyv_muladd_s16(v_scalar, b2, c2);
            
#line 318
            npyv_s16 abc3 = npyv_muladd_s16(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s16 b0 = npyv_load_s16(data + vstep * 0);
            npyv_s16 c0 = npyv_load_s16(data_out + vstep * 0);
            
#line 312
            npyv_s16 b1 = npyv_load_s16(data + vstep * 1);
            npyv_s16 c1 = npyv_load_s16(data_out + vstep * 1);
            
#line 312
            npyv_s16 b2 = npyv_load_s16(data + vstep * 2);
            npyv_s16 c2 = npyv_load_s16(data_out + vstep * 2);
            
#line 312
            npyv_s16 b3 = npyv_load_s16(data + vstep * 3);
            npyv_s16 c3 = npyv_load_s16(data_out + vstep * 3);
            
            #line 318
            npyv_s16 abc0 = npyv_muladd_s16(v_scalar, b0, c0);
            
#line 318
            npyv_s16 abc1 = npyv_muladd_s16(v_scalar, b1, c1);
            
#line 318
            npyv_s16 abc2 = npyv_muladd_s16(v_scalar, b2, c2);
            
#line 318
            npyv_s16 abc3 = npyv_muladd_s16(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data, count);
        npyv_s16 b = npyv_load_tillz_s16(data_out, count);
        npyv_store_till_s16(data_out, count, npyv_muladd_s16(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_short b0 = (data[0]);
        const npy_short c0 = (data_out[0]);
        
#line 340
        const npy_short b1 = (data[1]);
        const npy_short c1 = (data_out[1]);
        
#line 340
        const npy_short b2 = (data[2]);
        const npy_short c2 = (data_out[2]);
        
#line 340
        const npy_short b3 = (data[3]);
        const npy_short c3 = (data_out[3]);
        
        #line 346
        const npy_short abc0 = scalar * b0 + c0;
        
#line 346
        const npy_short abc1 = scalar * b1 + c1;
        
#line 346
        const npy_short abc2 = scalar * b2 + c2;
        
#line 346
        const npy_short abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_short b = (*data);
        const npy_short c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_short
}

static void
short_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data_out = (npy_short *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_short
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s16;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s16 a0 = npyv_loada_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_loada_s16(data1 + vstep * 0);
            npyv_s16 c0 = npyv_loada_s16(data_out + vstep * 0);
            
#line 390
            npyv_s16 a1 = npyv_loada_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_loada_s16(data1 + vstep * 1);
            npyv_s16 c1 = npyv_loada_s16(data_out + vstep * 1);
            
#line 390
            npyv_s16 a2 = npyv_loada_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_loada_s16(data1 + vstep * 2);
            npyv_s16 c2 = npyv_loada_s16(data_out + vstep * 2);
            
#line 390
            npyv_s16 a3 = npyv_loada_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_loada_s16(data1 + vstep * 3);
            npyv_s16 c3 = npyv_loada_s16(data_out + vstep * 3);
            
            #line 397
            npyv_s16 abc0 = npyv_muladd_s16(a0, b0, c0);
            
#line 397
            npyv_s16 abc1 = npyv_muladd_s16(a1, b1, c1);
            
#line 397
            npyv_s16 abc2 = npyv_muladd_s16(a2, b2, c2);
            
#line 397
            npyv_s16 abc3 = npyv_muladd_s16(a3, b3, c3);
            
            #line 402
            npyv_storea_s16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s16 a0 = npyv_load_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_load_s16(data1 + vstep * 0);
            npyv_s16 c0 = npyv_load_s16(data_out + vstep * 0);
            
#line 390
            npyv_s16 a1 = npyv_load_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_load_s16(data1 + vstep * 1);
            npyv_s16 c1 = npyv_load_s16(data_out + vstep * 1);
            
#line 390
            npyv_s16 a2 = npyv_load_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_load_s16(data1 + vstep * 2);
            npyv_s16 c2 = npyv_load_s16(data_out + vstep * 2);
            
#line 390
            npyv_s16 a3 = npyv_load_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_load_s16(data1 + vstep * 3);
            npyv_s16 c3 = npyv_load_s16(data_out + vstep * 3);
            
            #line 397
            npyv_s16 abc0 = npyv_muladd_s16(a0, b0, c0);
            
#line 397
            npyv_s16 abc1 = npyv_muladd_s16(a1, b1, c1);
            
#line 397
            npyv_s16 abc2 = npyv_muladd_s16(a2, b2, c2);
            
#line 397
            npyv_s16 abc3 = npyv_muladd_s16(a3, b3, c3);
            
            #line 402
            npyv_store_s16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data0, count);
        npyv_s16 b = npyv_load_tillz_s16(data1, count);
        npyv_s16 c = npyv_load_tillz_s16(data_out, count);
        npyv_store_till_s16(data_out, count, npyv_muladd_s16(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_short a0 = (data0[0]);
        const npy_short b0 = (data1[0]);
        const npy_short c0 = (data_out[0]);
        
#line 420
        const npy_short a1 = (data0[1]);
        const npy_short b1 = (data1[1]);
        const npy_short c1 = (data_out[1]);
        
#line 420
        const npy_short a2 = (data0[2]);
        const npy_short b2 = (data1[2]);
        const npy_short c2 = (data_out[2]);
        
#line 420
        const npy_short a3 = (data0[3]);
        const npy_short b3 = (data1[3]);
        const npy_short c3 = (data_out[3]);
        
        #line 427
        const npy_short abc0 = a0 * b0 + c0;
        
#line 427
        const npy_short abc1 = a1 * b1 + c1;
        
#line 427
        const npy_short abc2 = a2 * b2 + c2;
        
#line 427
        const npy_short abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_short a = (*data0);
        const npy_short b = (*data1);
        const npy_short c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_short

}

/* Some extra specializations for the two operand case */
static void
short_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short value0 = (*(npy_short *)dataptr[0]);
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data_out = (npy_short *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    short_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
short_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short value1 = (*(npy_short *)dataptr[1]);
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data_out = (npy_short *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    short_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short accum = 0;

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s16;
    npyv_s16 v_accum = npyv_zero_s16();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s16 a0 = npyv_loada_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_loada_s16(data1 + vstep * 0);
            
#line 501
            npyv_s16 a1 = npyv_loada_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_loada_s16(data1 + vstep * 1);
            
#line 501
            npyv_s16 a2 = npyv_loada_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_loada_s16(data1 + vstep * 2);
            
#line 501
            npyv_s16 a3 = npyv_loada_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_loada_s16(data1 + vstep * 3);
            
            npyv_s16 ab3 = npyv_muladd_s16(a3, b3, v_accum);
            npyv_s16 ab2 = npyv_muladd_s16(a2, b2, ab3);
            npyv_s16 ab1 = npyv_muladd_s16(a1, b1, ab2);
                   v_accum = npyv_muladd_s16(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s16 a0 = npyv_load_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_load_s16(data1 + vstep * 0);
            
#line 501
            npyv_s16 a1 = npyv_load_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_load_s16(data1 + vstep * 1);
            
#line 501
            npyv_s16 a2 = npyv_load_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_load_s16(data1 + vstep * 2);
            
#line 501
            npyv_s16 a3 = npyv_load_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_load_s16(data1 + vstep * 3);
            
            npyv_s16 ab3 = npyv_muladd_s16(a3, b3, v_accum);
            npyv_s16 ab2 = npyv_muladd_s16(a2, b2, ab3);
            npyv_s16 ab1 = npyv_muladd_s16(a1, b1, ab2);
                   v_accum = npyv_muladd_s16(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data0, count);
        npyv_s16 b = npyv_load_tillz_s16(data1, count);
        v_accum = npyv_muladd_s16(a, b, v_accum);
    }
    accum = npyv_sum_s16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_short ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_short ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_short ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_short ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_short a = (*data0);
        const npy_short b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_short
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short value0 = (*(npy_short *)dataptr[0]);
    npy_short accum = short_sum_of_arr(data1, count);
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short value1 = (*(npy_short *)dataptr[1]);
    npy_short accum = short_sum_of_arr(data0, count);
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
short_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data2 = (npy_short *)dataptr[2];
    npy_short *data_out = (npy_short *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
short_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        *(npy_short *)dataptr[nop] = (temp +
                                           (*(npy_short *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_short);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_short *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[0];
        ((npy_short *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_short);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_short *data = (npy_short *)dataptr[0];
    npy_short accum = short_sum_of_arr(data, count);
    *((npy_short *)dataptr[1]) = (accum + (*((npy_short *)dataptr[1])));
#else
    npy_short accum_re = 0, accum_im = 0;
    npy_short *data0 = (npy_short *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_short re01 = data0[0] + data0[2];
        const npy_short re23 = data0[4] + data0[6];
        const npy_short im13 = data0[1] + data0[3];
        const npy_short im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_short *)dataptr[1])[0] += accum_re;
    ((npy_short *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
short_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_short accum_re = 0, accum_im = 0;
#else
    npy_short accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_short *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_short *)data0) *
                 (*(npy_short *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_short *)data0) *
                 (*(npy_short *)data1) *
                 (*(npy_short *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_short *)data0)[0];
        accum_im += ((npy_short *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_short *)dataptr[2])[0] += accum_re;
    ((npy_short *)dataptr[2])[1] += accum_im;
#  else
    ((npy_short *)dataptr[nop])[0] += accum_re;
    ((npy_short *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_short *)dataptr[2]) = (accum +
                                    (*((npy_short *)dataptr[2])));
#  else
    *((npy_short *)dataptr[nop]) = (accum +
                                    (*((npy_short *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
short_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_short *)data_out = ((*(npy_short *)data0) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_short *)data_out = ((*(npy_short *)data0) *
                                         (*(npy_short *)data1) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_short *)data_out = ((*(npy_short *)data0) *
                                         (*(npy_short *)data1) *
                                         (*(npy_short *)data2) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        *(npy_short *)dataptr[nop] = (temp +
                                           (*(npy_short *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_short *)data_out)[0] = ((npy_short *)data0)[0] +
                                         ((npy_short *)data_out)[0];
        ((npy_short *)data_out)[1] = ((npy_short *)data0)[1] +
                                         ((npy_short *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_short *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[0];
        ((npy_short *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
short_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data_out = (npy_short *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_short *)data_out + 2*6)[0] =
                                    ((npy_short *)data0 + 2*6)[0] +
                                    ((npy_short *)data_out + 2*6)[0];
            ((npy_short *)data_out + 2*6)[1] =
                                    ((npy_short *)data0 + 2*6)[1] +
                                    ((npy_short *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_short *)data_out + 2*5)[0] =
                                    ((npy_short *)data0 + 2*5)[0] +
                                    ((npy_short *)data_out + 2*5)[0];
            ((npy_short *)data_out + 2*5)[1] =
                                    ((npy_short *)data0 + 2*5)[1] +
                                    ((npy_short *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_short *)data_out + 2*4)[0] =
                                    ((npy_short *)data0 + 2*4)[0] +
                                    ((npy_short *)data_out + 2*4)[0];
            ((npy_short *)data_out + 2*4)[1] =
                                    ((npy_short *)data0 + 2*4)[1] +
                                    ((npy_short *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_short *)data_out + 2*3)[0] =
                                    ((npy_short *)data0 + 2*3)[0] +
                                    ((npy_short *)data_out + 2*3)[0];
            ((npy_short *)data_out + 2*3)[1] =
                                    ((npy_short *)data0 + 2*3)[1] +
                                    ((npy_short *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_short *)data_out + 2*2)[0] =
                                    ((npy_short *)data0 + 2*2)[0] +
                                    ((npy_short *)data_out + 2*2)[0];
            ((npy_short *)data_out + 2*2)[1] =
                                    ((npy_short *)data0 + 2*2)[1] +
                                    ((npy_short *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_short *)data_out + 2*1)[0] =
                                    ((npy_short *)data0 + 2*1)[0] +
                                    ((npy_short *)data_out + 2*1)[0];
            ((npy_short *)data_out + 2*1)[1] =
                                    ((npy_short *)data0 + 2*1)[1] +
                                    ((npy_short *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_short *)data_out + 2*0)[0] =
                                    ((npy_short *)data0 + 2*0)[0] +
                                    ((npy_short *)data_out + 2*0)[0];
            ((npy_short *)data_out + 2*0)[1] =
                                    ((npy_short *)data0 + 2*0)[1] +
                                    ((npy_short *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_short *)data_out + 2*0)[0] =
                                ((npy_short *)data0 + 2*0)[0] +
                                ((npy_short *)data_out + 2*0)[0];
        ((npy_short *)data_out + 2*0)[1] =
                                ((npy_short *)data0 + 2*0)[1] +
                                ((npy_short *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_short *)data_out + 2*1)[0] =
                                ((npy_short *)data0 + 2*1)[0] +
                                ((npy_short *)data_out + 2*1)[0];
        ((npy_short *)data_out + 2*1)[1] =
                                ((npy_short *)data0 + 2*1)[1] +
                                ((npy_short *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_short *)data_out + 2*2)[0] =
                                ((npy_short *)data0 + 2*2)[0] +
                                ((npy_short *)data_out + 2*2)[0];
        ((npy_short *)data_out + 2*2)[1] =
                                ((npy_short *)data0 + 2*2)[1] +
                                ((npy_short *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_short *)data_out + 2*3)[0] =
                                ((npy_short *)data0 + 2*3)[0] +
                                ((npy_short *)data_out + 2*3)[0];
        ((npy_short *)data_out + 2*3)[1] =
                                ((npy_short *)data0 + 2*3)[1] +
                                ((npy_short *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_short *)data_out + 2*4)[0] =
                                ((npy_short *)data0 + 2*4)[0] +
                                ((npy_short *)data_out + 2*4)[0];
        ((npy_short *)data_out + 2*4)[1] =
                                ((npy_short *)data0 + 2*4)[1] +
                                ((npy_short *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_short *)data_out + 2*5)[0] =
                                ((npy_short *)data0 + 2*5)[0] +
                                ((npy_short *)data_out + 2*5)[0];
        ((npy_short *)data_out + 2*5)[1] =
                                ((npy_short *)data0 + 2*5)[1] +
                                ((npy_short *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_short *)data_out + 2*6)[0] =
                                ((npy_short *)data0 + 2*6)[0] +
                                ((npy_short *)data_out + 2*6)[0];
        ((npy_short *)data_out + 2*6)[1] =
                                ((npy_short *)data0 + 2*6)[1] +
                                ((npy_short *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_short *)data_out + 2*7)[0] =
                                ((npy_short *)data0 + 2*7)[0] +
                                ((npy_short *)data_out + 2*7)[0];
        ((npy_short *)data_out + 2*7)[1] =
                                ((npy_short *)data0 + 2*7)[1] +
                                ((npy_short *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
short_sum_of_products_muladd(npy_short *data, npy_short *data_out, npy_short scalar, npy_intp count)
{
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s16;
    const npyv_s16 v_scalar = npyv_setall_s16(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s16 b0 = npyv_loada_s16(data + vstep * 0);
            npyv_s16 c0 = npyv_loada_s16(data_out + vstep * 0);
            
#line 312
            npyv_s16 b1 = npyv_loada_s16(data + vstep * 1);
            npyv_s16 c1 = npyv_loada_s16(data_out + vstep * 1);
            
#line 312
            npyv_s16 b2 = npyv_loada_s16(data + vstep * 2);
            npyv_s16 c2 = npyv_loada_s16(data_out + vstep * 2);
            
#line 312
            npyv_s16 b3 = npyv_loada_s16(data + vstep * 3);
            npyv_s16 c3 = npyv_loada_s16(data_out + vstep * 3);
            
            #line 318
            npyv_s16 abc0 = npyv_muladd_s16(v_scalar, b0, c0);
            
#line 318
            npyv_s16 abc1 = npyv_muladd_s16(v_scalar, b1, c1);
            
#line 318
            npyv_s16 abc2 = npyv_muladd_s16(v_scalar, b2, c2);
            
#line 318
            npyv_s16 abc3 = npyv_muladd_s16(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s16 b0 = npyv_load_s16(data + vstep * 0);
            npyv_s16 c0 = npyv_load_s16(data_out + vstep * 0);
            
#line 312
            npyv_s16 b1 = npyv_load_s16(data + vstep * 1);
            npyv_s16 c1 = npyv_load_s16(data_out + vstep * 1);
            
#line 312
            npyv_s16 b2 = npyv_load_s16(data + vstep * 2);
            npyv_s16 c2 = npyv_load_s16(data_out + vstep * 2);
            
#line 312
            npyv_s16 b3 = npyv_load_s16(data + vstep * 3);
            npyv_s16 c3 = npyv_load_s16(data_out + vstep * 3);
            
            #line 318
            npyv_s16 abc0 = npyv_muladd_s16(v_scalar, b0, c0);
            
#line 318
            npyv_s16 abc1 = npyv_muladd_s16(v_scalar, b1, c1);
            
#line 318
            npyv_s16 abc2 = npyv_muladd_s16(v_scalar, b2, c2);
            
#line 318
            npyv_s16 abc3 = npyv_muladd_s16(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data, count);
        npyv_s16 b = npyv_load_tillz_s16(data_out, count);
        npyv_store_till_s16(data_out, count, npyv_muladd_s16(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_short b0 = (data[0]);
        const npy_short c0 = (data_out[0]);
        
#line 340
        const npy_short b1 = (data[1]);
        const npy_short c1 = (data_out[1]);
        
#line 340
        const npy_short b2 = (data[2]);
        const npy_short c2 = (data_out[2]);
        
#line 340
        const npy_short b3 = (data[3]);
        const npy_short c3 = (data_out[3]);
        
        #line 346
        const npy_short abc0 = scalar * b0 + c0;
        
#line 346
        const npy_short abc1 = scalar * b1 + c1;
        
#line 346
        const npy_short abc2 = scalar * b2 + c2;
        
#line 346
        const npy_short abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_short b = (*data);
        const npy_short c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_short
}

static void
short_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data_out = (npy_short *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_short
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s16;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s16 a0 = npyv_loada_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_loada_s16(data1 + vstep * 0);
            npyv_s16 c0 = npyv_loada_s16(data_out + vstep * 0);
            
#line 390
            npyv_s16 a1 = npyv_loada_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_loada_s16(data1 + vstep * 1);
            npyv_s16 c1 = npyv_loada_s16(data_out + vstep * 1);
            
#line 390
            npyv_s16 a2 = npyv_loada_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_loada_s16(data1 + vstep * 2);
            npyv_s16 c2 = npyv_loada_s16(data_out + vstep * 2);
            
#line 390
            npyv_s16 a3 = npyv_loada_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_loada_s16(data1 + vstep * 3);
            npyv_s16 c3 = npyv_loada_s16(data_out + vstep * 3);
            
            #line 397
            npyv_s16 abc0 = npyv_muladd_s16(a0, b0, c0);
            
#line 397
            npyv_s16 abc1 = npyv_muladd_s16(a1, b1, c1);
            
#line 397
            npyv_s16 abc2 = npyv_muladd_s16(a2, b2, c2);
            
#line 397
            npyv_s16 abc3 = npyv_muladd_s16(a3, b3, c3);
            
            #line 402
            npyv_storea_s16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s16 a0 = npyv_load_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_load_s16(data1 + vstep * 0);
            npyv_s16 c0 = npyv_load_s16(data_out + vstep * 0);
            
#line 390
            npyv_s16 a1 = npyv_load_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_load_s16(data1 + vstep * 1);
            npyv_s16 c1 = npyv_load_s16(data_out + vstep * 1);
            
#line 390
            npyv_s16 a2 = npyv_load_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_load_s16(data1 + vstep * 2);
            npyv_s16 c2 = npyv_load_s16(data_out + vstep * 2);
            
#line 390
            npyv_s16 a3 = npyv_load_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_load_s16(data1 + vstep * 3);
            npyv_s16 c3 = npyv_load_s16(data_out + vstep * 3);
            
            #line 397
            npyv_s16 abc0 = npyv_muladd_s16(a0, b0, c0);
            
#line 397
            npyv_s16 abc1 = npyv_muladd_s16(a1, b1, c1);
            
#line 397
            npyv_s16 abc2 = npyv_muladd_s16(a2, b2, c2);
            
#line 397
            npyv_s16 abc3 = npyv_muladd_s16(a3, b3, c3);
            
            #line 402
            npyv_store_s16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data0, count);
        npyv_s16 b = npyv_load_tillz_s16(data1, count);
        npyv_s16 c = npyv_load_tillz_s16(data_out, count);
        npyv_store_till_s16(data_out, count, npyv_muladd_s16(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_short a0 = (data0[0]);
        const npy_short b0 = (data1[0]);
        const npy_short c0 = (data_out[0]);
        
#line 420
        const npy_short a1 = (data0[1]);
        const npy_short b1 = (data1[1]);
        const npy_short c1 = (data_out[1]);
        
#line 420
        const npy_short a2 = (data0[2]);
        const npy_short b2 = (data1[2]);
        const npy_short c2 = (data_out[2]);
        
#line 420
        const npy_short a3 = (data0[3]);
        const npy_short b3 = (data1[3]);
        const npy_short c3 = (data_out[3]);
        
        #line 427
        const npy_short abc0 = a0 * b0 + c0;
        
#line 427
        const npy_short abc1 = a1 * b1 + c1;
        
#line 427
        const npy_short abc2 = a2 * b2 + c2;
        
#line 427
        const npy_short abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_short a = (*data0);
        const npy_short b = (*data1);
        const npy_short c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_short

}

/* Some extra specializations for the two operand case */
static void
short_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short value0 = (*(npy_short *)dataptr[0]);
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data_out = (npy_short *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    short_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
short_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short value1 = (*(npy_short *)dataptr[1]);
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data_out = (npy_short *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    short_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short accum = 0;

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s16;
    npyv_s16 v_accum = npyv_zero_s16();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s16 a0 = npyv_loada_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_loada_s16(data1 + vstep * 0);
            
#line 501
            npyv_s16 a1 = npyv_loada_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_loada_s16(data1 + vstep * 1);
            
#line 501
            npyv_s16 a2 = npyv_loada_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_loada_s16(data1 + vstep * 2);
            
#line 501
            npyv_s16 a3 = npyv_loada_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_loada_s16(data1 + vstep * 3);
            
            npyv_s16 ab3 = npyv_muladd_s16(a3, b3, v_accum);
            npyv_s16 ab2 = npyv_muladd_s16(a2, b2, ab3);
            npyv_s16 ab1 = npyv_muladd_s16(a1, b1, ab2);
                   v_accum = npyv_muladd_s16(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s16 a0 = npyv_load_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_load_s16(data1 + vstep * 0);
            
#line 501
            npyv_s16 a1 = npyv_load_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_load_s16(data1 + vstep * 1);
            
#line 501
            npyv_s16 a2 = npyv_load_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_load_s16(data1 + vstep * 2);
            
#line 501
            npyv_s16 a3 = npyv_load_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_load_s16(data1 + vstep * 3);
            
            npyv_s16 ab3 = npyv_muladd_s16(a3, b3, v_accum);
            npyv_s16 ab2 = npyv_muladd_s16(a2, b2, ab3);
            npyv_s16 ab1 = npyv_muladd_s16(a1, b1, ab2);
                   v_accum = npyv_muladd_s16(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data0, count);
        npyv_s16 b = npyv_load_tillz_s16(data1, count);
        v_accum = npyv_muladd_s16(a, b, v_accum);
    }
    accum = npyv_sum_s16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_short ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_short ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_short ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_short ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_short a = (*data0);
        const npy_short b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_short
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short value0 = (*(npy_short *)dataptr[0]);
    npy_short accum = short_sum_of_arr(data1, count);
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short value1 = (*(npy_short *)dataptr[1]);
    npy_short accum = short_sum_of_arr(data0, count);
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
short_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data2 = (npy_short *)dataptr[2];
    npy_short *data_out = (npy_short *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
short_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        *(npy_short *)dataptr[nop] = (temp +
                                           (*(npy_short *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_short);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_short *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[0];
        ((npy_short *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_short);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_short *data = (npy_short *)dataptr[0];
    npy_short accum = short_sum_of_arr(data, count);
    *((npy_short *)dataptr[1]) = (accum + (*((npy_short *)dataptr[1])));
#else
    npy_short accum_re = 0, accum_im = 0;
    npy_short *data0 = (npy_short *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_short re01 = data0[0] + data0[2];
        const npy_short re23 = data0[4] + data0[6];
        const npy_short im13 = data0[1] + data0[3];
        const npy_short im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_short *)dataptr[1])[0] += accum_re;
    ((npy_short *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
short_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_short accum_re = 0, accum_im = 0;
#else
    npy_short accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_short *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_short *)data0) *
                 (*(npy_short *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_short *)data0) *
                 (*(npy_short *)data1) *
                 (*(npy_short *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_short *)data0)[0];
        accum_im += ((npy_short *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_short *)dataptr[3])[0] += accum_re;
    ((npy_short *)dataptr[3])[1] += accum_im;
#  else
    ((npy_short *)dataptr[nop])[0] += accum_re;
    ((npy_short *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_short *)dataptr[3]) = (accum +
                                    (*((npy_short *)dataptr[3])));
#  else
    *((npy_short *)dataptr[nop]) = (accum +
                                    (*((npy_short *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
short_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_short *)data_out = ((*(npy_short *)data0) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_short *)data_out = ((*(npy_short *)data0) *
                                         (*(npy_short *)data1) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_short *)data_out = ((*(npy_short *)data0) *
                                         (*(npy_short *)data1) *
                                         (*(npy_short *)data2) +
                                         (*(npy_short *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        *(npy_short *)dataptr[nop] = (temp +
                                           (*(npy_short *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_short *)data_out)[0] = ((npy_short *)data0)[0] +
                                         ((npy_short *)data_out)[0];
        ((npy_short *)data_out)[1] = ((npy_short *)data0)[1] +
                                         ((npy_short *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_short *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[0];
        ((npy_short *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
short_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data_out = (npy_short *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_short *)data_out + 2*6)[0] =
                                    ((npy_short *)data0 + 2*6)[0] +
                                    ((npy_short *)data_out + 2*6)[0];
            ((npy_short *)data_out + 2*6)[1] =
                                    ((npy_short *)data0 + 2*6)[1] +
                                    ((npy_short *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_short *)data_out + 2*5)[0] =
                                    ((npy_short *)data0 + 2*5)[0] +
                                    ((npy_short *)data_out + 2*5)[0];
            ((npy_short *)data_out + 2*5)[1] =
                                    ((npy_short *)data0 + 2*5)[1] +
                                    ((npy_short *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_short *)data_out + 2*4)[0] =
                                    ((npy_short *)data0 + 2*4)[0] +
                                    ((npy_short *)data_out + 2*4)[0];
            ((npy_short *)data_out + 2*4)[1] =
                                    ((npy_short *)data0 + 2*4)[1] +
                                    ((npy_short *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_short *)data_out + 2*3)[0] =
                                    ((npy_short *)data0 + 2*3)[0] +
                                    ((npy_short *)data_out + 2*3)[0];
            ((npy_short *)data_out + 2*3)[1] =
                                    ((npy_short *)data0 + 2*3)[1] +
                                    ((npy_short *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_short *)data_out + 2*2)[0] =
                                    ((npy_short *)data0 + 2*2)[0] +
                                    ((npy_short *)data_out + 2*2)[0];
            ((npy_short *)data_out + 2*2)[1] =
                                    ((npy_short *)data0 + 2*2)[1] +
                                    ((npy_short *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_short *)data_out + 2*1)[0] =
                                    ((npy_short *)data0 + 2*1)[0] +
                                    ((npy_short *)data_out + 2*1)[0];
            ((npy_short *)data_out + 2*1)[1] =
                                    ((npy_short *)data0 + 2*1)[1] +
                                    ((npy_short *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_short *)data_out + 2*0)[0] =
                                    ((npy_short *)data0 + 2*0)[0] +
                                    ((npy_short *)data_out + 2*0)[0];
            ((npy_short *)data_out + 2*0)[1] =
                                    ((npy_short *)data0 + 2*0)[1] +
                                    ((npy_short *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_short *)data_out + 2*0)[0] =
                                ((npy_short *)data0 + 2*0)[0] +
                                ((npy_short *)data_out + 2*0)[0];
        ((npy_short *)data_out + 2*0)[1] =
                                ((npy_short *)data0 + 2*0)[1] +
                                ((npy_short *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_short *)data_out + 2*1)[0] =
                                ((npy_short *)data0 + 2*1)[0] +
                                ((npy_short *)data_out + 2*1)[0];
        ((npy_short *)data_out + 2*1)[1] =
                                ((npy_short *)data0 + 2*1)[1] +
                                ((npy_short *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_short *)data_out + 2*2)[0] =
                                ((npy_short *)data0 + 2*2)[0] +
                                ((npy_short *)data_out + 2*2)[0];
        ((npy_short *)data_out + 2*2)[1] =
                                ((npy_short *)data0 + 2*2)[1] +
                                ((npy_short *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_short *)data_out + 2*3)[0] =
                                ((npy_short *)data0 + 2*3)[0] +
                                ((npy_short *)data_out + 2*3)[0];
        ((npy_short *)data_out + 2*3)[1] =
                                ((npy_short *)data0 + 2*3)[1] +
                                ((npy_short *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_short *)data_out + 2*4)[0] =
                                ((npy_short *)data0 + 2*4)[0] +
                                ((npy_short *)data_out + 2*4)[0];
        ((npy_short *)data_out + 2*4)[1] =
                                ((npy_short *)data0 + 2*4)[1] +
                                ((npy_short *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_short *)data_out + 2*5)[0] =
                                ((npy_short *)data0 + 2*5)[0] +
                                ((npy_short *)data_out + 2*5)[0];
        ((npy_short *)data_out + 2*5)[1] =
                                ((npy_short *)data0 + 2*5)[1] +
                                ((npy_short *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_short *)data_out + 2*6)[0] =
                                ((npy_short *)data0 + 2*6)[0] +
                                ((npy_short *)data_out + 2*6)[0];
        ((npy_short *)data_out + 2*6)[1] =
                                ((npy_short *)data0 + 2*6)[1] +
                                ((npy_short *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_short *)data_out + 2*7)[0] =
                                ((npy_short *)data0 + 2*7)[0] +
                                ((npy_short *)data_out + 2*7)[0];
        ((npy_short *)data_out + 2*7)[1] =
                                ((npy_short *)data0 + 2*7)[1] +
                                ((npy_short *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
short_sum_of_products_muladd(npy_short *data, npy_short *data_out, npy_short scalar, npy_intp count)
{
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s16;
    const npyv_s16 v_scalar = npyv_setall_s16(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s16 b0 = npyv_loada_s16(data + vstep * 0);
            npyv_s16 c0 = npyv_loada_s16(data_out + vstep * 0);
            
#line 312
            npyv_s16 b1 = npyv_loada_s16(data + vstep * 1);
            npyv_s16 c1 = npyv_loada_s16(data_out + vstep * 1);
            
#line 312
            npyv_s16 b2 = npyv_loada_s16(data + vstep * 2);
            npyv_s16 c2 = npyv_loada_s16(data_out + vstep * 2);
            
#line 312
            npyv_s16 b3 = npyv_loada_s16(data + vstep * 3);
            npyv_s16 c3 = npyv_loada_s16(data_out + vstep * 3);
            
            #line 318
            npyv_s16 abc0 = npyv_muladd_s16(v_scalar, b0, c0);
            
#line 318
            npyv_s16 abc1 = npyv_muladd_s16(v_scalar, b1, c1);
            
#line 318
            npyv_s16 abc2 = npyv_muladd_s16(v_scalar, b2, c2);
            
#line 318
            npyv_s16 abc3 = npyv_muladd_s16(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s16 b0 = npyv_load_s16(data + vstep * 0);
            npyv_s16 c0 = npyv_load_s16(data_out + vstep * 0);
            
#line 312
            npyv_s16 b1 = npyv_load_s16(data + vstep * 1);
            npyv_s16 c1 = npyv_load_s16(data_out + vstep * 1);
            
#line 312
            npyv_s16 b2 = npyv_load_s16(data + vstep * 2);
            npyv_s16 c2 = npyv_load_s16(data_out + vstep * 2);
            
#line 312
            npyv_s16 b3 = npyv_load_s16(data + vstep * 3);
            npyv_s16 c3 = npyv_load_s16(data_out + vstep * 3);
            
            #line 318
            npyv_s16 abc0 = npyv_muladd_s16(v_scalar, b0, c0);
            
#line 318
            npyv_s16 abc1 = npyv_muladd_s16(v_scalar, b1, c1);
            
#line 318
            npyv_s16 abc2 = npyv_muladd_s16(v_scalar, b2, c2);
            
#line 318
            npyv_s16 abc3 = npyv_muladd_s16(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data, count);
        npyv_s16 b = npyv_load_tillz_s16(data_out, count);
        npyv_store_till_s16(data_out, count, npyv_muladd_s16(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_short b0 = (data[0]);
        const npy_short c0 = (data_out[0]);
        
#line 340
        const npy_short b1 = (data[1]);
        const npy_short c1 = (data_out[1]);
        
#line 340
        const npy_short b2 = (data[2]);
        const npy_short c2 = (data_out[2]);
        
#line 340
        const npy_short b3 = (data[3]);
        const npy_short c3 = (data_out[3]);
        
        #line 346
        const npy_short abc0 = scalar * b0 + c0;
        
#line 346
        const npy_short abc1 = scalar * b1 + c1;
        
#line 346
        const npy_short abc2 = scalar * b2 + c2;
        
#line 346
        const npy_short abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_short b = (*data);
        const npy_short c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_short
}

static void
short_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data_out = (npy_short *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_short
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s16;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s16 a0 = npyv_loada_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_loada_s16(data1 + vstep * 0);
            npyv_s16 c0 = npyv_loada_s16(data_out + vstep * 0);
            
#line 390
            npyv_s16 a1 = npyv_loada_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_loada_s16(data1 + vstep * 1);
            npyv_s16 c1 = npyv_loada_s16(data_out + vstep * 1);
            
#line 390
            npyv_s16 a2 = npyv_loada_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_loada_s16(data1 + vstep * 2);
            npyv_s16 c2 = npyv_loada_s16(data_out + vstep * 2);
            
#line 390
            npyv_s16 a3 = npyv_loada_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_loada_s16(data1 + vstep * 3);
            npyv_s16 c3 = npyv_loada_s16(data_out + vstep * 3);
            
            #line 397
            npyv_s16 abc0 = npyv_muladd_s16(a0, b0, c0);
            
#line 397
            npyv_s16 abc1 = npyv_muladd_s16(a1, b1, c1);
            
#line 397
            npyv_s16 abc2 = npyv_muladd_s16(a2, b2, c2);
            
#line 397
            npyv_s16 abc3 = npyv_muladd_s16(a3, b3, c3);
            
            #line 402
            npyv_storea_s16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s16 a0 = npyv_load_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_load_s16(data1 + vstep * 0);
            npyv_s16 c0 = npyv_load_s16(data_out + vstep * 0);
            
#line 390
            npyv_s16 a1 = npyv_load_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_load_s16(data1 + vstep * 1);
            npyv_s16 c1 = npyv_load_s16(data_out + vstep * 1);
            
#line 390
            npyv_s16 a2 = npyv_load_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_load_s16(data1 + vstep * 2);
            npyv_s16 c2 = npyv_load_s16(data_out + vstep * 2);
            
#line 390
            npyv_s16 a3 = npyv_load_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_load_s16(data1 + vstep * 3);
            npyv_s16 c3 = npyv_load_s16(data_out + vstep * 3);
            
            #line 397
            npyv_s16 abc0 = npyv_muladd_s16(a0, b0, c0);
            
#line 397
            npyv_s16 abc1 = npyv_muladd_s16(a1, b1, c1);
            
#line 397
            npyv_s16 abc2 = npyv_muladd_s16(a2, b2, c2);
            
#line 397
            npyv_s16 abc3 = npyv_muladd_s16(a3, b3, c3);
            
            #line 402
            npyv_store_s16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data0, count);
        npyv_s16 b = npyv_load_tillz_s16(data1, count);
        npyv_s16 c = npyv_load_tillz_s16(data_out, count);
        npyv_store_till_s16(data_out, count, npyv_muladd_s16(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_short a0 = (data0[0]);
        const npy_short b0 = (data1[0]);
        const npy_short c0 = (data_out[0]);
        
#line 420
        const npy_short a1 = (data0[1]);
        const npy_short b1 = (data1[1]);
        const npy_short c1 = (data_out[1]);
        
#line 420
        const npy_short a2 = (data0[2]);
        const npy_short b2 = (data1[2]);
        const npy_short c2 = (data_out[2]);
        
#line 420
        const npy_short a3 = (data0[3]);
        const npy_short b3 = (data1[3]);
        const npy_short c3 = (data_out[3]);
        
        #line 427
        const npy_short abc0 = a0 * b0 + c0;
        
#line 427
        const npy_short abc1 = a1 * b1 + c1;
        
#line 427
        const npy_short abc2 = a2 * b2 + c2;
        
#line 427
        const npy_short abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_short a = (*data0);
        const npy_short b = (*data1);
        const npy_short c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_short

}

/* Some extra specializations for the two operand case */
static void
short_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short value0 = (*(npy_short *)dataptr[0]);
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data_out = (npy_short *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    short_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
short_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short value1 = (*(npy_short *)dataptr[1]);
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data_out = (npy_short *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    short_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short accum = 0;

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_short
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s16;
    npyv_s16 v_accum = npyv_zero_s16();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s16 a0 = npyv_loada_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_loada_s16(data1 + vstep * 0);
            
#line 501
            npyv_s16 a1 = npyv_loada_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_loada_s16(data1 + vstep * 1);
            
#line 501
            npyv_s16 a2 = npyv_loada_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_loada_s16(data1 + vstep * 2);
            
#line 501
            npyv_s16 a3 = npyv_loada_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_loada_s16(data1 + vstep * 3);
            
            npyv_s16 ab3 = npyv_muladd_s16(a3, b3, v_accum);
            npyv_s16 ab2 = npyv_muladd_s16(a2, b2, ab3);
            npyv_s16 ab1 = npyv_muladd_s16(a1, b1, ab2);
                   v_accum = npyv_muladd_s16(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s16 a0 = npyv_load_s16(data0 + vstep * 0);
            npyv_s16 b0 = npyv_load_s16(data1 + vstep * 0);
            
#line 501
            npyv_s16 a1 = npyv_load_s16(data0 + vstep * 1);
            npyv_s16 b1 = npyv_load_s16(data1 + vstep * 1);
            
#line 501
            npyv_s16 a2 = npyv_load_s16(data0 + vstep * 2);
            npyv_s16 b2 = npyv_load_s16(data1 + vstep * 2);
            
#line 501
            npyv_s16 a3 = npyv_load_s16(data0 + vstep * 3);
            npyv_s16 b3 = npyv_load_s16(data1 + vstep * 3);
            
            npyv_s16 ab3 = npyv_muladd_s16(a3, b3, v_accum);
            npyv_s16 ab2 = npyv_muladd_s16(a2, b2, ab3);
            npyv_s16 ab1 = npyv_muladd_s16(a1, b1, ab2);
                   v_accum = npyv_muladd_s16(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s16 a = npyv_load_tillz_s16(data0, count);
        npyv_s16 b = npyv_load_tillz_s16(data1, count);
        v_accum = npyv_muladd_s16(a, b, v_accum);
    }
    accum = npyv_sum_s16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_short ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_short ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_short ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_short ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_short a = (*data0);
        const npy_short b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_short
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short value0 = (*(npy_short *)dataptr[0]);
    npy_short accum = short_sum_of_arr(data1, count);
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short value1 = (*(npy_short *)dataptr[1]);
    npy_short accum = short_sum_of_arr(data0, count);
    *(npy_short *)dataptr[2] = ((*(npy_short *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
short_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_short *data0 = (npy_short *)dataptr[0];
    npy_short *data1 = (npy_short *)dataptr[1];
    npy_short *data2 = (npy_short *)dataptr[2];
    npy_short *data_out = (npy_short *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
short_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        *(npy_short *)dataptr[nop] = (temp +
                                           (*(npy_short *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_short);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_short *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[0];
        ((npy_short *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_short *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_short);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
short_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_short *data = (npy_short *)dataptr[0];
    npy_short accum = short_sum_of_arr(data, count);
    *((npy_short *)dataptr[1]) = (accum + (*((npy_short *)dataptr[1])));
#else
    npy_short accum_re = 0, accum_im = 0;
    npy_short *data0 = (npy_short *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_short re01 = data0[0] + data0[2];
        const npy_short re23 = data0[4] + data0[6];
        const npy_short im13 = data0[1] + data0[3];
        const npy_short im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_short *)dataptr[1])[0] += accum_re;
    ((npy_short *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
short_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_short accum_re = 0, accum_im = 0;
#else
    npy_short accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("short_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_short *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_short *)data0) *
                 (*(npy_short *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_short *)data0) *
                 (*(npy_short *)data1) *
                 (*(npy_short *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_short temp = (*(npy_short *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_short *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_short *)data0)[0];
        accum_im += ((npy_short *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_short re, im, tmp;
        int i;
        re = ((npy_short *)dataptr[0])[0];
        im = ((npy_short *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_short *)dataptr[i])[0] -
                  im * ((npy_short *)dataptr[i])[1];
            im = re * ((npy_short *)dataptr[i])[1] +
                 im * ((npy_short *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_short *)dataptr[1000])[0] += accum_re;
    ((npy_short *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_short *)dataptr[nop])[0] += accum_re;
    ((npy_short *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_short *)dataptr[1000]) = (accum +
                                    (*((npy_short *)dataptr[1000])));
#  else
    *((npy_short *)dataptr[nop]) = (accum +
                                    (*((npy_short *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_int int_sum_of_arr(npy_int *data, npy_intp count)
{
    npy_int accum = 0;
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_s32;
    npyv_s32 v_accum = npyv_zero_s32();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_s32 a0 = npyv_loada_s32(data + vstep * 0);
            
#line 96
            npyv_s32 a1 = npyv_loada_s32(data + vstep * 1);
            
#line 96
            npyv_s32 a2 = npyv_loada_s32(data + vstep * 2);
            
#line 96
            npyv_s32 a3 = npyv_loada_s32(data + vstep * 3);
            
            npyv_s32 a01   = npyv_add_s32(a0, a1);
            npyv_s32 a23   = npyv_add_s32(a2, a3);
            npyv_s32 a0123 = npyv_add_s32(a01, a23);
                     v_accum = npyv_add_s32(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_s32 a0 = npyv_load_s32(data + vstep * 0);
            
#line 96
            npyv_s32 a1 = npyv_load_s32(data + vstep * 1);
            
#line 96
            npyv_s32 a2 = npyv_load_s32(data + vstep * 2);
            
#line 96
            npyv_s32 a3 = npyv_load_s32(data + vstep * 3);
            
            npyv_s32 a01   = npyv_add_s32(a0, a1);
            npyv_s32 a23   = npyv_add_s32(a2, a3);
            npyv_s32 a0123 = npyv_add_s32(a01, a23);
                     v_accum = npyv_add_s32(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data, count);
        v_accum = npyv_add_s32(a, v_accum);
    }
    accum = npyv_sum_s32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_int a01 = (*data) + (data[1]);
        const npy_int a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_int
    return accum;
}
#endif

#line 131
static void
int_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_int *)data_out = ((*(npy_int *)data0) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_int *)data_out = ((*(npy_int *)data0) *
                                         (*(npy_int *)data1) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_int *)data_out = ((*(npy_int *)data0) *
                                         (*(npy_int *)data1) *
                                         (*(npy_int *)data2) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        *(npy_int *)dataptr[nop] = (temp +
                                           (*(npy_int *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_int *)data_out)[0] = ((npy_int *)data0)[0] +
                                         ((npy_int *)data_out)[0];
        ((npy_int *)data_out)[1] = ((npy_int *)data0)[1] +
                                         ((npy_int *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_int *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[0];
        ((npy_int *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
int_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data_out = (npy_int *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_int *)data_out + 2*6)[0] =
                                    ((npy_int *)data0 + 2*6)[0] +
                                    ((npy_int *)data_out + 2*6)[0];
            ((npy_int *)data_out + 2*6)[1] =
                                    ((npy_int *)data0 + 2*6)[1] +
                                    ((npy_int *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_int *)data_out + 2*5)[0] =
                                    ((npy_int *)data0 + 2*5)[0] +
                                    ((npy_int *)data_out + 2*5)[0];
            ((npy_int *)data_out + 2*5)[1] =
                                    ((npy_int *)data0 + 2*5)[1] +
                                    ((npy_int *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_int *)data_out + 2*4)[0] =
                                    ((npy_int *)data0 + 2*4)[0] +
                                    ((npy_int *)data_out + 2*4)[0];
            ((npy_int *)data_out + 2*4)[1] =
                                    ((npy_int *)data0 + 2*4)[1] +
                                    ((npy_int *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_int *)data_out + 2*3)[0] =
                                    ((npy_int *)data0 + 2*3)[0] +
                                    ((npy_int *)data_out + 2*3)[0];
            ((npy_int *)data_out + 2*3)[1] =
                                    ((npy_int *)data0 + 2*3)[1] +
                                    ((npy_int *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_int *)data_out + 2*2)[0] =
                                    ((npy_int *)data0 + 2*2)[0] +
                                    ((npy_int *)data_out + 2*2)[0];
            ((npy_int *)data_out + 2*2)[1] =
                                    ((npy_int *)data0 + 2*2)[1] +
                                    ((npy_int *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_int *)data_out + 2*1)[0] =
                                    ((npy_int *)data0 + 2*1)[0] +
                                    ((npy_int *)data_out + 2*1)[0];
            ((npy_int *)data_out + 2*1)[1] =
                                    ((npy_int *)data0 + 2*1)[1] +
                                    ((npy_int *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_int *)data_out + 2*0)[0] =
                                    ((npy_int *)data0 + 2*0)[0] +
                                    ((npy_int *)data_out + 2*0)[0];
            ((npy_int *)data_out + 2*0)[1] =
                                    ((npy_int *)data0 + 2*0)[1] +
                                    ((npy_int *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_int *)data_out + 2*0)[0] =
                                ((npy_int *)data0 + 2*0)[0] +
                                ((npy_int *)data_out + 2*0)[0];
        ((npy_int *)data_out + 2*0)[1] =
                                ((npy_int *)data0 + 2*0)[1] +
                                ((npy_int *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_int *)data_out + 2*1)[0] =
                                ((npy_int *)data0 + 2*1)[0] +
                                ((npy_int *)data_out + 2*1)[0];
        ((npy_int *)data_out + 2*1)[1] =
                                ((npy_int *)data0 + 2*1)[1] +
                                ((npy_int *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_int *)data_out + 2*2)[0] =
                                ((npy_int *)data0 + 2*2)[0] +
                                ((npy_int *)data_out + 2*2)[0];
        ((npy_int *)data_out + 2*2)[1] =
                                ((npy_int *)data0 + 2*2)[1] +
                                ((npy_int *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_int *)data_out + 2*3)[0] =
                                ((npy_int *)data0 + 2*3)[0] +
                                ((npy_int *)data_out + 2*3)[0];
        ((npy_int *)data_out + 2*3)[1] =
                                ((npy_int *)data0 + 2*3)[1] +
                                ((npy_int *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_int *)data_out + 2*4)[0] =
                                ((npy_int *)data0 + 2*4)[0] +
                                ((npy_int *)data_out + 2*4)[0];
        ((npy_int *)data_out + 2*4)[1] =
                                ((npy_int *)data0 + 2*4)[1] +
                                ((npy_int *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_int *)data_out + 2*5)[0] =
                                ((npy_int *)data0 + 2*5)[0] +
                                ((npy_int *)data_out + 2*5)[0];
        ((npy_int *)data_out + 2*5)[1] =
                                ((npy_int *)data0 + 2*5)[1] +
                                ((npy_int *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_int *)data_out + 2*6)[0] =
                                ((npy_int *)data0 + 2*6)[0] +
                                ((npy_int *)data_out + 2*6)[0];
        ((npy_int *)data_out + 2*6)[1] =
                                ((npy_int *)data0 + 2*6)[1] +
                                ((npy_int *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_int *)data_out + 2*7)[0] =
                                ((npy_int *)data0 + 2*7)[0] +
                                ((npy_int *)data_out + 2*7)[0];
        ((npy_int *)data_out + 2*7)[1] =
                                ((npy_int *)data0 + 2*7)[1] +
                                ((npy_int *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
int_sum_of_products_muladd(npy_int *data, npy_int *data_out, npy_int scalar, npy_intp count)
{
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s32;
    const npyv_s32 v_scalar = npyv_setall_s32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s32 b0 = npyv_loada_s32(data + vstep * 0);
            npyv_s32 c0 = npyv_loada_s32(data_out + vstep * 0);
            
#line 312
            npyv_s32 b1 = npyv_loada_s32(data + vstep * 1);
            npyv_s32 c1 = npyv_loada_s32(data_out + vstep * 1);
            
#line 312
            npyv_s32 b2 = npyv_loada_s32(data + vstep * 2);
            npyv_s32 c2 = npyv_loada_s32(data_out + vstep * 2);
            
#line 312
            npyv_s32 b3 = npyv_loada_s32(data + vstep * 3);
            npyv_s32 c3 = npyv_loada_s32(data_out + vstep * 3);
            
            #line 318
            npyv_s32 abc0 = npyv_muladd_s32(v_scalar, b0, c0);
            
#line 318
            npyv_s32 abc1 = npyv_muladd_s32(v_scalar, b1, c1);
            
#line 318
            npyv_s32 abc2 = npyv_muladd_s32(v_scalar, b2, c2);
            
#line 318
            npyv_s32 abc3 = npyv_muladd_s32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s32 b0 = npyv_load_s32(data + vstep * 0);
            npyv_s32 c0 = npyv_load_s32(data_out + vstep * 0);
            
#line 312
            npyv_s32 b1 = npyv_load_s32(data + vstep * 1);
            npyv_s32 c1 = npyv_load_s32(data_out + vstep * 1);
            
#line 312
            npyv_s32 b2 = npyv_load_s32(data + vstep * 2);
            npyv_s32 c2 = npyv_load_s32(data_out + vstep * 2);
            
#line 312
            npyv_s32 b3 = npyv_load_s32(data + vstep * 3);
            npyv_s32 c3 = npyv_load_s32(data_out + vstep * 3);
            
            #line 318
            npyv_s32 abc0 = npyv_muladd_s32(v_scalar, b0, c0);
            
#line 318
            npyv_s32 abc1 = npyv_muladd_s32(v_scalar, b1, c1);
            
#line 318
            npyv_s32 abc2 = npyv_muladd_s32(v_scalar, b2, c2);
            
#line 318
            npyv_s32 abc3 = npyv_muladd_s32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data, count);
        npyv_s32 b = npyv_load_tillz_s32(data_out, count);
        npyv_store_till_s32(data_out, count, npyv_muladd_s32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_int b0 = (data[0]);
        const npy_int c0 = (data_out[0]);
        
#line 340
        const npy_int b1 = (data[1]);
        const npy_int c1 = (data_out[1]);
        
#line 340
        const npy_int b2 = (data[2]);
        const npy_int c2 = (data_out[2]);
        
#line 340
        const npy_int b3 = (data[3]);
        const npy_int c3 = (data_out[3]);
        
        #line 346
        const npy_int abc0 = scalar * b0 + c0;
        
#line 346
        const npy_int abc1 = scalar * b1 + c1;
        
#line 346
        const npy_int abc2 = scalar * b2 + c2;
        
#line 346
        const npy_int abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_int b = (*data);
        const npy_int c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_int
}

static void
int_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data_out = (npy_int *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_int
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s32 a0 = npyv_loada_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_loada_s32(data1 + vstep * 0);
            npyv_s32 c0 = npyv_loada_s32(data_out + vstep * 0);
            
#line 390
            npyv_s32 a1 = npyv_loada_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_loada_s32(data1 + vstep * 1);
            npyv_s32 c1 = npyv_loada_s32(data_out + vstep * 1);
            
#line 390
            npyv_s32 a2 = npyv_loada_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_loada_s32(data1 + vstep * 2);
            npyv_s32 c2 = npyv_loada_s32(data_out + vstep * 2);
            
#line 390
            npyv_s32 a3 = npyv_loada_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_loada_s32(data1 + vstep * 3);
            npyv_s32 c3 = npyv_loada_s32(data_out + vstep * 3);
            
            #line 397
            npyv_s32 abc0 = npyv_muladd_s32(a0, b0, c0);
            
#line 397
            npyv_s32 abc1 = npyv_muladd_s32(a1, b1, c1);
            
#line 397
            npyv_s32 abc2 = npyv_muladd_s32(a2, b2, c2);
            
#line 397
            npyv_s32 abc3 = npyv_muladd_s32(a3, b3, c3);
            
            #line 402
            npyv_storea_s32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s32 a0 = npyv_load_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_load_s32(data1 + vstep * 0);
            npyv_s32 c0 = npyv_load_s32(data_out + vstep * 0);
            
#line 390
            npyv_s32 a1 = npyv_load_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_load_s32(data1 + vstep * 1);
            npyv_s32 c1 = npyv_load_s32(data_out + vstep * 1);
            
#line 390
            npyv_s32 a2 = npyv_load_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_load_s32(data1 + vstep * 2);
            npyv_s32 c2 = npyv_load_s32(data_out + vstep * 2);
            
#line 390
            npyv_s32 a3 = npyv_load_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_load_s32(data1 + vstep * 3);
            npyv_s32 c3 = npyv_load_s32(data_out + vstep * 3);
            
            #line 397
            npyv_s32 abc0 = npyv_muladd_s32(a0, b0, c0);
            
#line 397
            npyv_s32 abc1 = npyv_muladd_s32(a1, b1, c1);
            
#line 397
            npyv_s32 abc2 = npyv_muladd_s32(a2, b2, c2);
            
#line 397
            npyv_s32 abc3 = npyv_muladd_s32(a3, b3, c3);
            
            #line 402
            npyv_store_s32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data0, count);
        npyv_s32 b = npyv_load_tillz_s32(data1, count);
        npyv_s32 c = npyv_load_tillz_s32(data_out, count);
        npyv_store_till_s32(data_out, count, npyv_muladd_s32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_int a0 = (data0[0]);
        const npy_int b0 = (data1[0]);
        const npy_int c0 = (data_out[0]);
        
#line 420
        const npy_int a1 = (data0[1]);
        const npy_int b1 = (data1[1]);
        const npy_int c1 = (data_out[1]);
        
#line 420
        const npy_int a2 = (data0[2]);
        const npy_int b2 = (data1[2]);
        const npy_int c2 = (data_out[2]);
        
#line 420
        const npy_int a3 = (data0[3]);
        const npy_int b3 = (data1[3]);
        const npy_int c3 = (data_out[3]);
        
        #line 427
        const npy_int abc0 = a0 * b0 + c0;
        
#line 427
        const npy_int abc1 = a1 * b1 + c1;
        
#line 427
        const npy_int abc2 = a2 * b2 + c2;
        
#line 427
        const npy_int abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_int a = (*data0);
        const npy_int b = (*data1);
        const npy_int c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_int

}

/* Some extra specializations for the two operand case */
static void
int_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int value0 = (*(npy_int *)dataptr[0]);
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data_out = (npy_int *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    int_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
int_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int value1 = (*(npy_int *)dataptr[1]);
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data_out = (npy_int *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    int_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int accum = 0;

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s32;
    npyv_s32 v_accum = npyv_zero_s32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s32 a0 = npyv_loada_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_loada_s32(data1 + vstep * 0);
            
#line 501
            npyv_s32 a1 = npyv_loada_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_loada_s32(data1 + vstep * 1);
            
#line 501
            npyv_s32 a2 = npyv_loada_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_loada_s32(data1 + vstep * 2);
            
#line 501
            npyv_s32 a3 = npyv_loada_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_loada_s32(data1 + vstep * 3);
            
            npyv_s32 ab3 = npyv_muladd_s32(a3, b3, v_accum);
            npyv_s32 ab2 = npyv_muladd_s32(a2, b2, ab3);
            npyv_s32 ab1 = npyv_muladd_s32(a1, b1, ab2);
                   v_accum = npyv_muladd_s32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s32 a0 = npyv_load_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_load_s32(data1 + vstep * 0);
            
#line 501
            npyv_s32 a1 = npyv_load_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_load_s32(data1 + vstep * 1);
            
#line 501
            npyv_s32 a2 = npyv_load_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_load_s32(data1 + vstep * 2);
            
#line 501
            npyv_s32 a3 = npyv_load_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_load_s32(data1 + vstep * 3);
            
            npyv_s32 ab3 = npyv_muladd_s32(a3, b3, v_accum);
            npyv_s32 ab2 = npyv_muladd_s32(a2, b2, ab3);
            npyv_s32 ab1 = npyv_muladd_s32(a1, b1, ab2);
                   v_accum = npyv_muladd_s32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data0, count);
        npyv_s32 b = npyv_load_tillz_s32(data1, count);
        v_accum = npyv_muladd_s32(a, b, v_accum);
    }
    accum = npyv_sum_s32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_int ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_int ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_int ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_int ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_int a = (*data0);
        const npy_int b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_int
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int value0 = (*(npy_int *)dataptr[0]);
    npy_int accum = int_sum_of_arr(data1, count);
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int value1 = (*(npy_int *)dataptr[1]);
    npy_int accum = int_sum_of_arr(data0, count);
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
int_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data2 = (npy_int *)dataptr[2];
    npy_int *data_out = (npy_int *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
int_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        *(npy_int *)dataptr[nop] = (temp +
                                           (*(npy_int *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_int);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_int *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[0];
        ((npy_int *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_int);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_int *data = (npy_int *)dataptr[0];
    npy_int accum = int_sum_of_arr(data, count);
    *((npy_int *)dataptr[1]) = (accum + (*((npy_int *)dataptr[1])));
#else
    npy_int accum_re = 0, accum_im = 0;
    npy_int *data0 = (npy_int *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_int re01 = data0[0] + data0[2];
        const npy_int re23 = data0[4] + data0[6];
        const npy_int im13 = data0[1] + data0[3];
        const npy_int im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_int *)dataptr[1])[0] += accum_re;
    ((npy_int *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
int_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_int accum_re = 0, accum_im = 0;
#else
    npy_int accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_int *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_int *)data0) *
                 (*(npy_int *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_int *)data0) *
                 (*(npy_int *)data1) *
                 (*(npy_int *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_int *)data0)[0];
        accum_im += ((npy_int *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_int *)dataptr[1])[0] += accum_re;
    ((npy_int *)dataptr[1])[1] += accum_im;
#  else
    ((npy_int *)dataptr[nop])[0] += accum_re;
    ((npy_int *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_int *)dataptr[1]) = (accum +
                                    (*((npy_int *)dataptr[1])));
#  else
    *((npy_int *)dataptr[nop]) = (accum +
                                    (*((npy_int *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
int_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_int *)data_out = ((*(npy_int *)data0) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_int *)data_out = ((*(npy_int *)data0) *
                                         (*(npy_int *)data1) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_int *)data_out = ((*(npy_int *)data0) *
                                         (*(npy_int *)data1) *
                                         (*(npy_int *)data2) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        *(npy_int *)dataptr[nop] = (temp +
                                           (*(npy_int *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_int *)data_out)[0] = ((npy_int *)data0)[0] +
                                         ((npy_int *)data_out)[0];
        ((npy_int *)data_out)[1] = ((npy_int *)data0)[1] +
                                         ((npy_int *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_int *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[0];
        ((npy_int *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
int_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data_out = (npy_int *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_int *)data_out + 2*6)[0] =
                                    ((npy_int *)data0 + 2*6)[0] +
                                    ((npy_int *)data_out + 2*6)[0];
            ((npy_int *)data_out + 2*6)[1] =
                                    ((npy_int *)data0 + 2*6)[1] +
                                    ((npy_int *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_int *)data_out + 2*5)[0] =
                                    ((npy_int *)data0 + 2*5)[0] +
                                    ((npy_int *)data_out + 2*5)[0];
            ((npy_int *)data_out + 2*5)[1] =
                                    ((npy_int *)data0 + 2*5)[1] +
                                    ((npy_int *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_int *)data_out + 2*4)[0] =
                                    ((npy_int *)data0 + 2*4)[0] +
                                    ((npy_int *)data_out + 2*4)[0];
            ((npy_int *)data_out + 2*4)[1] =
                                    ((npy_int *)data0 + 2*4)[1] +
                                    ((npy_int *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_int *)data_out + 2*3)[0] =
                                    ((npy_int *)data0 + 2*3)[0] +
                                    ((npy_int *)data_out + 2*3)[0];
            ((npy_int *)data_out + 2*3)[1] =
                                    ((npy_int *)data0 + 2*3)[1] +
                                    ((npy_int *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_int *)data_out + 2*2)[0] =
                                    ((npy_int *)data0 + 2*2)[0] +
                                    ((npy_int *)data_out + 2*2)[0];
            ((npy_int *)data_out + 2*2)[1] =
                                    ((npy_int *)data0 + 2*2)[1] +
                                    ((npy_int *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_int *)data_out + 2*1)[0] =
                                    ((npy_int *)data0 + 2*1)[0] +
                                    ((npy_int *)data_out + 2*1)[0];
            ((npy_int *)data_out + 2*1)[1] =
                                    ((npy_int *)data0 + 2*1)[1] +
                                    ((npy_int *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_int *)data_out + 2*0)[0] =
                                    ((npy_int *)data0 + 2*0)[0] +
                                    ((npy_int *)data_out + 2*0)[0];
            ((npy_int *)data_out + 2*0)[1] =
                                    ((npy_int *)data0 + 2*0)[1] +
                                    ((npy_int *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_int *)data_out + 2*0)[0] =
                                ((npy_int *)data0 + 2*0)[0] +
                                ((npy_int *)data_out + 2*0)[0];
        ((npy_int *)data_out + 2*0)[1] =
                                ((npy_int *)data0 + 2*0)[1] +
                                ((npy_int *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_int *)data_out + 2*1)[0] =
                                ((npy_int *)data0 + 2*1)[0] +
                                ((npy_int *)data_out + 2*1)[0];
        ((npy_int *)data_out + 2*1)[1] =
                                ((npy_int *)data0 + 2*1)[1] +
                                ((npy_int *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_int *)data_out + 2*2)[0] =
                                ((npy_int *)data0 + 2*2)[0] +
                                ((npy_int *)data_out + 2*2)[0];
        ((npy_int *)data_out + 2*2)[1] =
                                ((npy_int *)data0 + 2*2)[1] +
                                ((npy_int *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_int *)data_out + 2*3)[0] =
                                ((npy_int *)data0 + 2*3)[0] +
                                ((npy_int *)data_out + 2*3)[0];
        ((npy_int *)data_out + 2*3)[1] =
                                ((npy_int *)data0 + 2*3)[1] +
                                ((npy_int *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_int *)data_out + 2*4)[0] =
                                ((npy_int *)data0 + 2*4)[0] +
                                ((npy_int *)data_out + 2*4)[0];
        ((npy_int *)data_out + 2*4)[1] =
                                ((npy_int *)data0 + 2*4)[1] +
                                ((npy_int *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_int *)data_out + 2*5)[0] =
                                ((npy_int *)data0 + 2*5)[0] +
                                ((npy_int *)data_out + 2*5)[0];
        ((npy_int *)data_out + 2*5)[1] =
                                ((npy_int *)data0 + 2*5)[1] +
                                ((npy_int *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_int *)data_out + 2*6)[0] =
                                ((npy_int *)data0 + 2*6)[0] +
                                ((npy_int *)data_out + 2*6)[0];
        ((npy_int *)data_out + 2*6)[1] =
                                ((npy_int *)data0 + 2*6)[1] +
                                ((npy_int *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_int *)data_out + 2*7)[0] =
                                ((npy_int *)data0 + 2*7)[0] +
                                ((npy_int *)data_out + 2*7)[0];
        ((npy_int *)data_out + 2*7)[1] =
                                ((npy_int *)data0 + 2*7)[1] +
                                ((npy_int *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
int_sum_of_products_muladd(npy_int *data, npy_int *data_out, npy_int scalar, npy_intp count)
{
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s32;
    const npyv_s32 v_scalar = npyv_setall_s32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s32 b0 = npyv_loada_s32(data + vstep * 0);
            npyv_s32 c0 = npyv_loada_s32(data_out + vstep * 0);
            
#line 312
            npyv_s32 b1 = npyv_loada_s32(data + vstep * 1);
            npyv_s32 c1 = npyv_loada_s32(data_out + vstep * 1);
            
#line 312
            npyv_s32 b2 = npyv_loada_s32(data + vstep * 2);
            npyv_s32 c2 = npyv_loada_s32(data_out + vstep * 2);
            
#line 312
            npyv_s32 b3 = npyv_loada_s32(data + vstep * 3);
            npyv_s32 c3 = npyv_loada_s32(data_out + vstep * 3);
            
            #line 318
            npyv_s32 abc0 = npyv_muladd_s32(v_scalar, b0, c0);
            
#line 318
            npyv_s32 abc1 = npyv_muladd_s32(v_scalar, b1, c1);
            
#line 318
            npyv_s32 abc2 = npyv_muladd_s32(v_scalar, b2, c2);
            
#line 318
            npyv_s32 abc3 = npyv_muladd_s32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s32 b0 = npyv_load_s32(data + vstep * 0);
            npyv_s32 c0 = npyv_load_s32(data_out + vstep * 0);
            
#line 312
            npyv_s32 b1 = npyv_load_s32(data + vstep * 1);
            npyv_s32 c1 = npyv_load_s32(data_out + vstep * 1);
            
#line 312
            npyv_s32 b2 = npyv_load_s32(data + vstep * 2);
            npyv_s32 c2 = npyv_load_s32(data_out + vstep * 2);
            
#line 312
            npyv_s32 b3 = npyv_load_s32(data + vstep * 3);
            npyv_s32 c3 = npyv_load_s32(data_out + vstep * 3);
            
            #line 318
            npyv_s32 abc0 = npyv_muladd_s32(v_scalar, b0, c0);
            
#line 318
            npyv_s32 abc1 = npyv_muladd_s32(v_scalar, b1, c1);
            
#line 318
            npyv_s32 abc2 = npyv_muladd_s32(v_scalar, b2, c2);
            
#line 318
            npyv_s32 abc3 = npyv_muladd_s32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data, count);
        npyv_s32 b = npyv_load_tillz_s32(data_out, count);
        npyv_store_till_s32(data_out, count, npyv_muladd_s32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_int b0 = (data[0]);
        const npy_int c0 = (data_out[0]);
        
#line 340
        const npy_int b1 = (data[1]);
        const npy_int c1 = (data_out[1]);
        
#line 340
        const npy_int b2 = (data[2]);
        const npy_int c2 = (data_out[2]);
        
#line 340
        const npy_int b3 = (data[3]);
        const npy_int c3 = (data_out[3]);
        
        #line 346
        const npy_int abc0 = scalar * b0 + c0;
        
#line 346
        const npy_int abc1 = scalar * b1 + c1;
        
#line 346
        const npy_int abc2 = scalar * b2 + c2;
        
#line 346
        const npy_int abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_int b = (*data);
        const npy_int c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_int
}

static void
int_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data_out = (npy_int *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_int
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s32 a0 = npyv_loada_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_loada_s32(data1 + vstep * 0);
            npyv_s32 c0 = npyv_loada_s32(data_out + vstep * 0);
            
#line 390
            npyv_s32 a1 = npyv_loada_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_loada_s32(data1 + vstep * 1);
            npyv_s32 c1 = npyv_loada_s32(data_out + vstep * 1);
            
#line 390
            npyv_s32 a2 = npyv_loada_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_loada_s32(data1 + vstep * 2);
            npyv_s32 c2 = npyv_loada_s32(data_out + vstep * 2);
            
#line 390
            npyv_s32 a3 = npyv_loada_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_loada_s32(data1 + vstep * 3);
            npyv_s32 c3 = npyv_loada_s32(data_out + vstep * 3);
            
            #line 397
            npyv_s32 abc0 = npyv_muladd_s32(a0, b0, c0);
            
#line 397
            npyv_s32 abc1 = npyv_muladd_s32(a1, b1, c1);
            
#line 397
            npyv_s32 abc2 = npyv_muladd_s32(a2, b2, c2);
            
#line 397
            npyv_s32 abc3 = npyv_muladd_s32(a3, b3, c3);
            
            #line 402
            npyv_storea_s32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s32 a0 = npyv_load_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_load_s32(data1 + vstep * 0);
            npyv_s32 c0 = npyv_load_s32(data_out + vstep * 0);
            
#line 390
            npyv_s32 a1 = npyv_load_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_load_s32(data1 + vstep * 1);
            npyv_s32 c1 = npyv_load_s32(data_out + vstep * 1);
            
#line 390
            npyv_s32 a2 = npyv_load_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_load_s32(data1 + vstep * 2);
            npyv_s32 c2 = npyv_load_s32(data_out + vstep * 2);
            
#line 390
            npyv_s32 a3 = npyv_load_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_load_s32(data1 + vstep * 3);
            npyv_s32 c3 = npyv_load_s32(data_out + vstep * 3);
            
            #line 397
            npyv_s32 abc0 = npyv_muladd_s32(a0, b0, c0);
            
#line 397
            npyv_s32 abc1 = npyv_muladd_s32(a1, b1, c1);
            
#line 397
            npyv_s32 abc2 = npyv_muladd_s32(a2, b2, c2);
            
#line 397
            npyv_s32 abc3 = npyv_muladd_s32(a3, b3, c3);
            
            #line 402
            npyv_store_s32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data0, count);
        npyv_s32 b = npyv_load_tillz_s32(data1, count);
        npyv_s32 c = npyv_load_tillz_s32(data_out, count);
        npyv_store_till_s32(data_out, count, npyv_muladd_s32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_int a0 = (data0[0]);
        const npy_int b0 = (data1[0]);
        const npy_int c0 = (data_out[0]);
        
#line 420
        const npy_int a1 = (data0[1]);
        const npy_int b1 = (data1[1]);
        const npy_int c1 = (data_out[1]);
        
#line 420
        const npy_int a2 = (data0[2]);
        const npy_int b2 = (data1[2]);
        const npy_int c2 = (data_out[2]);
        
#line 420
        const npy_int a3 = (data0[3]);
        const npy_int b3 = (data1[3]);
        const npy_int c3 = (data_out[3]);
        
        #line 427
        const npy_int abc0 = a0 * b0 + c0;
        
#line 427
        const npy_int abc1 = a1 * b1 + c1;
        
#line 427
        const npy_int abc2 = a2 * b2 + c2;
        
#line 427
        const npy_int abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_int a = (*data0);
        const npy_int b = (*data1);
        const npy_int c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_int

}

/* Some extra specializations for the two operand case */
static void
int_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int value0 = (*(npy_int *)dataptr[0]);
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data_out = (npy_int *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    int_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
int_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int value1 = (*(npy_int *)dataptr[1]);
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data_out = (npy_int *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    int_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int accum = 0;

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s32;
    npyv_s32 v_accum = npyv_zero_s32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s32 a0 = npyv_loada_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_loada_s32(data1 + vstep * 0);
            
#line 501
            npyv_s32 a1 = npyv_loada_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_loada_s32(data1 + vstep * 1);
            
#line 501
            npyv_s32 a2 = npyv_loada_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_loada_s32(data1 + vstep * 2);
            
#line 501
            npyv_s32 a3 = npyv_loada_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_loada_s32(data1 + vstep * 3);
            
            npyv_s32 ab3 = npyv_muladd_s32(a3, b3, v_accum);
            npyv_s32 ab2 = npyv_muladd_s32(a2, b2, ab3);
            npyv_s32 ab1 = npyv_muladd_s32(a1, b1, ab2);
                   v_accum = npyv_muladd_s32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s32 a0 = npyv_load_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_load_s32(data1 + vstep * 0);
            
#line 501
            npyv_s32 a1 = npyv_load_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_load_s32(data1 + vstep * 1);
            
#line 501
            npyv_s32 a2 = npyv_load_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_load_s32(data1 + vstep * 2);
            
#line 501
            npyv_s32 a3 = npyv_load_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_load_s32(data1 + vstep * 3);
            
            npyv_s32 ab3 = npyv_muladd_s32(a3, b3, v_accum);
            npyv_s32 ab2 = npyv_muladd_s32(a2, b2, ab3);
            npyv_s32 ab1 = npyv_muladd_s32(a1, b1, ab2);
                   v_accum = npyv_muladd_s32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data0, count);
        npyv_s32 b = npyv_load_tillz_s32(data1, count);
        v_accum = npyv_muladd_s32(a, b, v_accum);
    }
    accum = npyv_sum_s32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_int ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_int ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_int ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_int ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_int a = (*data0);
        const npy_int b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_int
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int value0 = (*(npy_int *)dataptr[0]);
    npy_int accum = int_sum_of_arr(data1, count);
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int value1 = (*(npy_int *)dataptr[1]);
    npy_int accum = int_sum_of_arr(data0, count);
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
int_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data2 = (npy_int *)dataptr[2];
    npy_int *data_out = (npy_int *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
int_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        *(npy_int *)dataptr[nop] = (temp +
                                           (*(npy_int *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_int);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_int *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[0];
        ((npy_int *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_int);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_int *data = (npy_int *)dataptr[0];
    npy_int accum = int_sum_of_arr(data, count);
    *((npy_int *)dataptr[1]) = (accum + (*((npy_int *)dataptr[1])));
#else
    npy_int accum_re = 0, accum_im = 0;
    npy_int *data0 = (npy_int *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_int re01 = data0[0] + data0[2];
        const npy_int re23 = data0[4] + data0[6];
        const npy_int im13 = data0[1] + data0[3];
        const npy_int im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_int *)dataptr[1])[0] += accum_re;
    ((npy_int *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
int_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_int accum_re = 0, accum_im = 0;
#else
    npy_int accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_int *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_int *)data0) *
                 (*(npy_int *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_int *)data0) *
                 (*(npy_int *)data1) *
                 (*(npy_int *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_int *)data0)[0];
        accum_im += ((npy_int *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_int *)dataptr[2])[0] += accum_re;
    ((npy_int *)dataptr[2])[1] += accum_im;
#  else
    ((npy_int *)dataptr[nop])[0] += accum_re;
    ((npy_int *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_int *)dataptr[2]) = (accum +
                                    (*((npy_int *)dataptr[2])));
#  else
    *((npy_int *)dataptr[nop]) = (accum +
                                    (*((npy_int *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
int_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_int *)data_out = ((*(npy_int *)data0) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_int *)data_out = ((*(npy_int *)data0) *
                                         (*(npy_int *)data1) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_int *)data_out = ((*(npy_int *)data0) *
                                         (*(npy_int *)data1) *
                                         (*(npy_int *)data2) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        *(npy_int *)dataptr[nop] = (temp +
                                           (*(npy_int *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_int *)data_out)[0] = ((npy_int *)data0)[0] +
                                         ((npy_int *)data_out)[0];
        ((npy_int *)data_out)[1] = ((npy_int *)data0)[1] +
                                         ((npy_int *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_int *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[0];
        ((npy_int *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
int_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data_out = (npy_int *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_int *)data_out + 2*6)[0] =
                                    ((npy_int *)data0 + 2*6)[0] +
                                    ((npy_int *)data_out + 2*6)[0];
            ((npy_int *)data_out + 2*6)[1] =
                                    ((npy_int *)data0 + 2*6)[1] +
                                    ((npy_int *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_int *)data_out + 2*5)[0] =
                                    ((npy_int *)data0 + 2*5)[0] +
                                    ((npy_int *)data_out + 2*5)[0];
            ((npy_int *)data_out + 2*5)[1] =
                                    ((npy_int *)data0 + 2*5)[1] +
                                    ((npy_int *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_int *)data_out + 2*4)[0] =
                                    ((npy_int *)data0 + 2*4)[0] +
                                    ((npy_int *)data_out + 2*4)[0];
            ((npy_int *)data_out + 2*4)[1] =
                                    ((npy_int *)data0 + 2*4)[1] +
                                    ((npy_int *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_int *)data_out + 2*3)[0] =
                                    ((npy_int *)data0 + 2*3)[0] +
                                    ((npy_int *)data_out + 2*3)[0];
            ((npy_int *)data_out + 2*3)[1] =
                                    ((npy_int *)data0 + 2*3)[1] +
                                    ((npy_int *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_int *)data_out + 2*2)[0] =
                                    ((npy_int *)data0 + 2*2)[0] +
                                    ((npy_int *)data_out + 2*2)[0];
            ((npy_int *)data_out + 2*2)[1] =
                                    ((npy_int *)data0 + 2*2)[1] +
                                    ((npy_int *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_int *)data_out + 2*1)[0] =
                                    ((npy_int *)data0 + 2*1)[0] +
                                    ((npy_int *)data_out + 2*1)[0];
            ((npy_int *)data_out + 2*1)[1] =
                                    ((npy_int *)data0 + 2*1)[1] +
                                    ((npy_int *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_int *)data_out + 2*0)[0] =
                                    ((npy_int *)data0 + 2*0)[0] +
                                    ((npy_int *)data_out + 2*0)[0];
            ((npy_int *)data_out + 2*0)[1] =
                                    ((npy_int *)data0 + 2*0)[1] +
                                    ((npy_int *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_int *)data_out + 2*0)[0] =
                                ((npy_int *)data0 + 2*0)[0] +
                                ((npy_int *)data_out + 2*0)[0];
        ((npy_int *)data_out + 2*0)[1] =
                                ((npy_int *)data0 + 2*0)[1] +
                                ((npy_int *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_int *)data_out + 2*1)[0] =
                                ((npy_int *)data0 + 2*1)[0] +
                                ((npy_int *)data_out + 2*1)[0];
        ((npy_int *)data_out + 2*1)[1] =
                                ((npy_int *)data0 + 2*1)[1] +
                                ((npy_int *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_int *)data_out + 2*2)[0] =
                                ((npy_int *)data0 + 2*2)[0] +
                                ((npy_int *)data_out + 2*2)[0];
        ((npy_int *)data_out + 2*2)[1] =
                                ((npy_int *)data0 + 2*2)[1] +
                                ((npy_int *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_int *)data_out + 2*3)[0] =
                                ((npy_int *)data0 + 2*3)[0] +
                                ((npy_int *)data_out + 2*3)[0];
        ((npy_int *)data_out + 2*3)[1] =
                                ((npy_int *)data0 + 2*3)[1] +
                                ((npy_int *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_int *)data_out + 2*4)[0] =
                                ((npy_int *)data0 + 2*4)[0] +
                                ((npy_int *)data_out + 2*4)[0];
        ((npy_int *)data_out + 2*4)[1] =
                                ((npy_int *)data0 + 2*4)[1] +
                                ((npy_int *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_int *)data_out + 2*5)[0] =
                                ((npy_int *)data0 + 2*5)[0] +
                                ((npy_int *)data_out + 2*5)[0];
        ((npy_int *)data_out + 2*5)[1] =
                                ((npy_int *)data0 + 2*5)[1] +
                                ((npy_int *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_int *)data_out + 2*6)[0] =
                                ((npy_int *)data0 + 2*6)[0] +
                                ((npy_int *)data_out + 2*6)[0];
        ((npy_int *)data_out + 2*6)[1] =
                                ((npy_int *)data0 + 2*6)[1] +
                                ((npy_int *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_int *)data_out + 2*7)[0] =
                                ((npy_int *)data0 + 2*7)[0] +
                                ((npy_int *)data_out + 2*7)[0];
        ((npy_int *)data_out + 2*7)[1] =
                                ((npy_int *)data0 + 2*7)[1] +
                                ((npy_int *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
int_sum_of_products_muladd(npy_int *data, npy_int *data_out, npy_int scalar, npy_intp count)
{
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s32;
    const npyv_s32 v_scalar = npyv_setall_s32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s32 b0 = npyv_loada_s32(data + vstep * 0);
            npyv_s32 c0 = npyv_loada_s32(data_out + vstep * 0);
            
#line 312
            npyv_s32 b1 = npyv_loada_s32(data + vstep * 1);
            npyv_s32 c1 = npyv_loada_s32(data_out + vstep * 1);
            
#line 312
            npyv_s32 b2 = npyv_loada_s32(data + vstep * 2);
            npyv_s32 c2 = npyv_loada_s32(data_out + vstep * 2);
            
#line 312
            npyv_s32 b3 = npyv_loada_s32(data + vstep * 3);
            npyv_s32 c3 = npyv_loada_s32(data_out + vstep * 3);
            
            #line 318
            npyv_s32 abc0 = npyv_muladd_s32(v_scalar, b0, c0);
            
#line 318
            npyv_s32 abc1 = npyv_muladd_s32(v_scalar, b1, c1);
            
#line 318
            npyv_s32 abc2 = npyv_muladd_s32(v_scalar, b2, c2);
            
#line 318
            npyv_s32 abc3 = npyv_muladd_s32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s32 b0 = npyv_load_s32(data + vstep * 0);
            npyv_s32 c0 = npyv_load_s32(data_out + vstep * 0);
            
#line 312
            npyv_s32 b1 = npyv_load_s32(data + vstep * 1);
            npyv_s32 c1 = npyv_load_s32(data_out + vstep * 1);
            
#line 312
            npyv_s32 b2 = npyv_load_s32(data + vstep * 2);
            npyv_s32 c2 = npyv_load_s32(data_out + vstep * 2);
            
#line 312
            npyv_s32 b3 = npyv_load_s32(data + vstep * 3);
            npyv_s32 c3 = npyv_load_s32(data_out + vstep * 3);
            
            #line 318
            npyv_s32 abc0 = npyv_muladd_s32(v_scalar, b0, c0);
            
#line 318
            npyv_s32 abc1 = npyv_muladd_s32(v_scalar, b1, c1);
            
#line 318
            npyv_s32 abc2 = npyv_muladd_s32(v_scalar, b2, c2);
            
#line 318
            npyv_s32 abc3 = npyv_muladd_s32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data, count);
        npyv_s32 b = npyv_load_tillz_s32(data_out, count);
        npyv_store_till_s32(data_out, count, npyv_muladd_s32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_int b0 = (data[0]);
        const npy_int c0 = (data_out[0]);
        
#line 340
        const npy_int b1 = (data[1]);
        const npy_int c1 = (data_out[1]);
        
#line 340
        const npy_int b2 = (data[2]);
        const npy_int c2 = (data_out[2]);
        
#line 340
        const npy_int b3 = (data[3]);
        const npy_int c3 = (data_out[3]);
        
        #line 346
        const npy_int abc0 = scalar * b0 + c0;
        
#line 346
        const npy_int abc1 = scalar * b1 + c1;
        
#line 346
        const npy_int abc2 = scalar * b2 + c2;
        
#line 346
        const npy_int abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_int b = (*data);
        const npy_int c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_int
}

static void
int_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data_out = (npy_int *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_int
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s32 a0 = npyv_loada_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_loada_s32(data1 + vstep * 0);
            npyv_s32 c0 = npyv_loada_s32(data_out + vstep * 0);
            
#line 390
            npyv_s32 a1 = npyv_loada_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_loada_s32(data1 + vstep * 1);
            npyv_s32 c1 = npyv_loada_s32(data_out + vstep * 1);
            
#line 390
            npyv_s32 a2 = npyv_loada_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_loada_s32(data1 + vstep * 2);
            npyv_s32 c2 = npyv_loada_s32(data_out + vstep * 2);
            
#line 390
            npyv_s32 a3 = npyv_loada_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_loada_s32(data1 + vstep * 3);
            npyv_s32 c3 = npyv_loada_s32(data_out + vstep * 3);
            
            #line 397
            npyv_s32 abc0 = npyv_muladd_s32(a0, b0, c0);
            
#line 397
            npyv_s32 abc1 = npyv_muladd_s32(a1, b1, c1);
            
#line 397
            npyv_s32 abc2 = npyv_muladd_s32(a2, b2, c2);
            
#line 397
            npyv_s32 abc3 = npyv_muladd_s32(a3, b3, c3);
            
            #line 402
            npyv_storea_s32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s32 a0 = npyv_load_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_load_s32(data1 + vstep * 0);
            npyv_s32 c0 = npyv_load_s32(data_out + vstep * 0);
            
#line 390
            npyv_s32 a1 = npyv_load_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_load_s32(data1 + vstep * 1);
            npyv_s32 c1 = npyv_load_s32(data_out + vstep * 1);
            
#line 390
            npyv_s32 a2 = npyv_load_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_load_s32(data1 + vstep * 2);
            npyv_s32 c2 = npyv_load_s32(data_out + vstep * 2);
            
#line 390
            npyv_s32 a3 = npyv_load_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_load_s32(data1 + vstep * 3);
            npyv_s32 c3 = npyv_load_s32(data_out + vstep * 3);
            
            #line 397
            npyv_s32 abc0 = npyv_muladd_s32(a0, b0, c0);
            
#line 397
            npyv_s32 abc1 = npyv_muladd_s32(a1, b1, c1);
            
#line 397
            npyv_s32 abc2 = npyv_muladd_s32(a2, b2, c2);
            
#line 397
            npyv_s32 abc3 = npyv_muladd_s32(a3, b3, c3);
            
            #line 402
            npyv_store_s32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data0, count);
        npyv_s32 b = npyv_load_tillz_s32(data1, count);
        npyv_s32 c = npyv_load_tillz_s32(data_out, count);
        npyv_store_till_s32(data_out, count, npyv_muladd_s32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_int a0 = (data0[0]);
        const npy_int b0 = (data1[0]);
        const npy_int c0 = (data_out[0]);
        
#line 420
        const npy_int a1 = (data0[1]);
        const npy_int b1 = (data1[1]);
        const npy_int c1 = (data_out[1]);
        
#line 420
        const npy_int a2 = (data0[2]);
        const npy_int b2 = (data1[2]);
        const npy_int c2 = (data_out[2]);
        
#line 420
        const npy_int a3 = (data0[3]);
        const npy_int b3 = (data1[3]);
        const npy_int c3 = (data_out[3]);
        
        #line 427
        const npy_int abc0 = a0 * b0 + c0;
        
#line 427
        const npy_int abc1 = a1 * b1 + c1;
        
#line 427
        const npy_int abc2 = a2 * b2 + c2;
        
#line 427
        const npy_int abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_int a = (*data0);
        const npy_int b = (*data1);
        const npy_int c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_int

}

/* Some extra specializations for the two operand case */
static void
int_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int value0 = (*(npy_int *)dataptr[0]);
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data_out = (npy_int *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    int_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
int_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int value1 = (*(npy_int *)dataptr[1]);
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data_out = (npy_int *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    int_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int accum = 0;

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s32;
    npyv_s32 v_accum = npyv_zero_s32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s32 a0 = npyv_loada_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_loada_s32(data1 + vstep * 0);
            
#line 501
            npyv_s32 a1 = npyv_loada_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_loada_s32(data1 + vstep * 1);
            
#line 501
            npyv_s32 a2 = npyv_loada_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_loada_s32(data1 + vstep * 2);
            
#line 501
            npyv_s32 a3 = npyv_loada_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_loada_s32(data1 + vstep * 3);
            
            npyv_s32 ab3 = npyv_muladd_s32(a3, b3, v_accum);
            npyv_s32 ab2 = npyv_muladd_s32(a2, b2, ab3);
            npyv_s32 ab1 = npyv_muladd_s32(a1, b1, ab2);
                   v_accum = npyv_muladd_s32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s32 a0 = npyv_load_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_load_s32(data1 + vstep * 0);
            
#line 501
            npyv_s32 a1 = npyv_load_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_load_s32(data1 + vstep * 1);
            
#line 501
            npyv_s32 a2 = npyv_load_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_load_s32(data1 + vstep * 2);
            
#line 501
            npyv_s32 a3 = npyv_load_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_load_s32(data1 + vstep * 3);
            
            npyv_s32 ab3 = npyv_muladd_s32(a3, b3, v_accum);
            npyv_s32 ab2 = npyv_muladd_s32(a2, b2, ab3);
            npyv_s32 ab1 = npyv_muladd_s32(a1, b1, ab2);
                   v_accum = npyv_muladd_s32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data0, count);
        npyv_s32 b = npyv_load_tillz_s32(data1, count);
        v_accum = npyv_muladd_s32(a, b, v_accum);
    }
    accum = npyv_sum_s32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_int ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_int ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_int ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_int ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_int a = (*data0);
        const npy_int b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_int
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int value0 = (*(npy_int *)dataptr[0]);
    npy_int accum = int_sum_of_arr(data1, count);
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int value1 = (*(npy_int *)dataptr[1]);
    npy_int accum = int_sum_of_arr(data0, count);
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
int_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data2 = (npy_int *)dataptr[2];
    npy_int *data_out = (npy_int *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
int_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        *(npy_int *)dataptr[nop] = (temp +
                                           (*(npy_int *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_int);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_int *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[0];
        ((npy_int *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_int);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_int *data = (npy_int *)dataptr[0];
    npy_int accum = int_sum_of_arr(data, count);
    *((npy_int *)dataptr[1]) = (accum + (*((npy_int *)dataptr[1])));
#else
    npy_int accum_re = 0, accum_im = 0;
    npy_int *data0 = (npy_int *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_int re01 = data0[0] + data0[2];
        const npy_int re23 = data0[4] + data0[6];
        const npy_int im13 = data0[1] + data0[3];
        const npy_int im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_int *)dataptr[1])[0] += accum_re;
    ((npy_int *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
int_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_int accum_re = 0, accum_im = 0;
#else
    npy_int accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_int *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_int *)data0) *
                 (*(npy_int *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_int *)data0) *
                 (*(npy_int *)data1) *
                 (*(npy_int *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_int *)data0)[0];
        accum_im += ((npy_int *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_int *)dataptr[3])[0] += accum_re;
    ((npy_int *)dataptr[3])[1] += accum_im;
#  else
    ((npy_int *)dataptr[nop])[0] += accum_re;
    ((npy_int *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_int *)dataptr[3]) = (accum +
                                    (*((npy_int *)dataptr[3])));
#  else
    *((npy_int *)dataptr[nop]) = (accum +
                                    (*((npy_int *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
int_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_int *)data_out = ((*(npy_int *)data0) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_int *)data_out = ((*(npy_int *)data0) *
                                         (*(npy_int *)data1) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_int *)data_out = ((*(npy_int *)data0) *
                                         (*(npy_int *)data1) *
                                         (*(npy_int *)data2) +
                                         (*(npy_int *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        *(npy_int *)dataptr[nop] = (temp +
                                           (*(npy_int *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_int *)data_out)[0] = ((npy_int *)data0)[0] +
                                         ((npy_int *)data_out)[0];
        ((npy_int *)data_out)[1] = ((npy_int *)data0)[1] +
                                         ((npy_int *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_int *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[0];
        ((npy_int *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
int_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data_out = (npy_int *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_int *)data_out + 2*6)[0] =
                                    ((npy_int *)data0 + 2*6)[0] +
                                    ((npy_int *)data_out + 2*6)[0];
            ((npy_int *)data_out + 2*6)[1] =
                                    ((npy_int *)data0 + 2*6)[1] +
                                    ((npy_int *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_int *)data_out + 2*5)[0] =
                                    ((npy_int *)data0 + 2*5)[0] +
                                    ((npy_int *)data_out + 2*5)[0];
            ((npy_int *)data_out + 2*5)[1] =
                                    ((npy_int *)data0 + 2*5)[1] +
                                    ((npy_int *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_int *)data_out + 2*4)[0] =
                                    ((npy_int *)data0 + 2*4)[0] +
                                    ((npy_int *)data_out + 2*4)[0];
            ((npy_int *)data_out + 2*4)[1] =
                                    ((npy_int *)data0 + 2*4)[1] +
                                    ((npy_int *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_int *)data_out + 2*3)[0] =
                                    ((npy_int *)data0 + 2*3)[0] +
                                    ((npy_int *)data_out + 2*3)[0];
            ((npy_int *)data_out + 2*3)[1] =
                                    ((npy_int *)data0 + 2*3)[1] +
                                    ((npy_int *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_int *)data_out + 2*2)[0] =
                                    ((npy_int *)data0 + 2*2)[0] +
                                    ((npy_int *)data_out + 2*2)[0];
            ((npy_int *)data_out + 2*2)[1] =
                                    ((npy_int *)data0 + 2*2)[1] +
                                    ((npy_int *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_int *)data_out + 2*1)[0] =
                                    ((npy_int *)data0 + 2*1)[0] +
                                    ((npy_int *)data_out + 2*1)[0];
            ((npy_int *)data_out + 2*1)[1] =
                                    ((npy_int *)data0 + 2*1)[1] +
                                    ((npy_int *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_int *)data_out + 2*0)[0] =
                                    ((npy_int *)data0 + 2*0)[0] +
                                    ((npy_int *)data_out + 2*0)[0];
            ((npy_int *)data_out + 2*0)[1] =
                                    ((npy_int *)data0 + 2*0)[1] +
                                    ((npy_int *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_int *)data_out + 2*0)[0] =
                                ((npy_int *)data0 + 2*0)[0] +
                                ((npy_int *)data_out + 2*0)[0];
        ((npy_int *)data_out + 2*0)[1] =
                                ((npy_int *)data0 + 2*0)[1] +
                                ((npy_int *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_int *)data_out + 2*1)[0] =
                                ((npy_int *)data0 + 2*1)[0] +
                                ((npy_int *)data_out + 2*1)[0];
        ((npy_int *)data_out + 2*1)[1] =
                                ((npy_int *)data0 + 2*1)[1] +
                                ((npy_int *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_int *)data_out + 2*2)[0] =
                                ((npy_int *)data0 + 2*2)[0] +
                                ((npy_int *)data_out + 2*2)[0];
        ((npy_int *)data_out + 2*2)[1] =
                                ((npy_int *)data0 + 2*2)[1] +
                                ((npy_int *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_int *)data_out + 2*3)[0] =
                                ((npy_int *)data0 + 2*3)[0] +
                                ((npy_int *)data_out + 2*3)[0];
        ((npy_int *)data_out + 2*3)[1] =
                                ((npy_int *)data0 + 2*3)[1] +
                                ((npy_int *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_int *)data_out + 2*4)[0] =
                                ((npy_int *)data0 + 2*4)[0] +
                                ((npy_int *)data_out + 2*4)[0];
        ((npy_int *)data_out + 2*4)[1] =
                                ((npy_int *)data0 + 2*4)[1] +
                                ((npy_int *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_int *)data_out + 2*5)[0] =
                                ((npy_int *)data0 + 2*5)[0] +
                                ((npy_int *)data_out + 2*5)[0];
        ((npy_int *)data_out + 2*5)[1] =
                                ((npy_int *)data0 + 2*5)[1] +
                                ((npy_int *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_int *)data_out + 2*6)[0] =
                                ((npy_int *)data0 + 2*6)[0] +
                                ((npy_int *)data_out + 2*6)[0];
        ((npy_int *)data_out + 2*6)[1] =
                                ((npy_int *)data0 + 2*6)[1] +
                                ((npy_int *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_int *)data_out + 2*7)[0] =
                                ((npy_int *)data0 + 2*7)[0] +
                                ((npy_int *)data_out + 2*7)[0];
        ((npy_int *)data_out + 2*7)[1] =
                                ((npy_int *)data0 + 2*7)[1] +
                                ((npy_int *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
int_sum_of_products_muladd(npy_int *data, npy_int *data_out, npy_int scalar, npy_intp count)
{
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s32;
    const npyv_s32 v_scalar = npyv_setall_s32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s32 b0 = npyv_loada_s32(data + vstep * 0);
            npyv_s32 c0 = npyv_loada_s32(data_out + vstep * 0);
            
#line 312
            npyv_s32 b1 = npyv_loada_s32(data + vstep * 1);
            npyv_s32 c1 = npyv_loada_s32(data_out + vstep * 1);
            
#line 312
            npyv_s32 b2 = npyv_loada_s32(data + vstep * 2);
            npyv_s32 c2 = npyv_loada_s32(data_out + vstep * 2);
            
#line 312
            npyv_s32 b3 = npyv_loada_s32(data + vstep * 3);
            npyv_s32 c3 = npyv_loada_s32(data_out + vstep * 3);
            
            #line 318
            npyv_s32 abc0 = npyv_muladd_s32(v_scalar, b0, c0);
            
#line 318
            npyv_s32 abc1 = npyv_muladd_s32(v_scalar, b1, c1);
            
#line 318
            npyv_s32 abc2 = npyv_muladd_s32(v_scalar, b2, c2);
            
#line 318
            npyv_s32 abc3 = npyv_muladd_s32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s32 b0 = npyv_load_s32(data + vstep * 0);
            npyv_s32 c0 = npyv_load_s32(data_out + vstep * 0);
            
#line 312
            npyv_s32 b1 = npyv_load_s32(data + vstep * 1);
            npyv_s32 c1 = npyv_load_s32(data_out + vstep * 1);
            
#line 312
            npyv_s32 b2 = npyv_load_s32(data + vstep * 2);
            npyv_s32 c2 = npyv_load_s32(data_out + vstep * 2);
            
#line 312
            npyv_s32 b3 = npyv_load_s32(data + vstep * 3);
            npyv_s32 c3 = npyv_load_s32(data_out + vstep * 3);
            
            #line 318
            npyv_s32 abc0 = npyv_muladd_s32(v_scalar, b0, c0);
            
#line 318
            npyv_s32 abc1 = npyv_muladd_s32(v_scalar, b1, c1);
            
#line 318
            npyv_s32 abc2 = npyv_muladd_s32(v_scalar, b2, c2);
            
#line 318
            npyv_s32 abc3 = npyv_muladd_s32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data, count);
        npyv_s32 b = npyv_load_tillz_s32(data_out, count);
        npyv_store_till_s32(data_out, count, npyv_muladd_s32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_int b0 = (data[0]);
        const npy_int c0 = (data_out[0]);
        
#line 340
        const npy_int b1 = (data[1]);
        const npy_int c1 = (data_out[1]);
        
#line 340
        const npy_int b2 = (data[2]);
        const npy_int c2 = (data_out[2]);
        
#line 340
        const npy_int b3 = (data[3]);
        const npy_int c3 = (data_out[3]);
        
        #line 346
        const npy_int abc0 = scalar * b0 + c0;
        
#line 346
        const npy_int abc1 = scalar * b1 + c1;
        
#line 346
        const npy_int abc2 = scalar * b2 + c2;
        
#line 346
        const npy_int abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_int b = (*data);
        const npy_int c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_int
}

static void
int_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data_out = (npy_int *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_int
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s32 a0 = npyv_loada_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_loada_s32(data1 + vstep * 0);
            npyv_s32 c0 = npyv_loada_s32(data_out + vstep * 0);
            
#line 390
            npyv_s32 a1 = npyv_loada_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_loada_s32(data1 + vstep * 1);
            npyv_s32 c1 = npyv_loada_s32(data_out + vstep * 1);
            
#line 390
            npyv_s32 a2 = npyv_loada_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_loada_s32(data1 + vstep * 2);
            npyv_s32 c2 = npyv_loada_s32(data_out + vstep * 2);
            
#line 390
            npyv_s32 a3 = npyv_loada_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_loada_s32(data1 + vstep * 3);
            npyv_s32 c3 = npyv_loada_s32(data_out + vstep * 3);
            
            #line 397
            npyv_s32 abc0 = npyv_muladd_s32(a0, b0, c0);
            
#line 397
            npyv_s32 abc1 = npyv_muladd_s32(a1, b1, c1);
            
#line 397
            npyv_s32 abc2 = npyv_muladd_s32(a2, b2, c2);
            
#line 397
            npyv_s32 abc3 = npyv_muladd_s32(a3, b3, c3);
            
            #line 402
            npyv_storea_s32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s32 a0 = npyv_load_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_load_s32(data1 + vstep * 0);
            npyv_s32 c0 = npyv_load_s32(data_out + vstep * 0);
            
#line 390
            npyv_s32 a1 = npyv_load_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_load_s32(data1 + vstep * 1);
            npyv_s32 c1 = npyv_load_s32(data_out + vstep * 1);
            
#line 390
            npyv_s32 a2 = npyv_load_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_load_s32(data1 + vstep * 2);
            npyv_s32 c2 = npyv_load_s32(data_out + vstep * 2);
            
#line 390
            npyv_s32 a3 = npyv_load_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_load_s32(data1 + vstep * 3);
            npyv_s32 c3 = npyv_load_s32(data_out + vstep * 3);
            
            #line 397
            npyv_s32 abc0 = npyv_muladd_s32(a0, b0, c0);
            
#line 397
            npyv_s32 abc1 = npyv_muladd_s32(a1, b1, c1);
            
#line 397
            npyv_s32 abc2 = npyv_muladd_s32(a2, b2, c2);
            
#line 397
            npyv_s32 abc3 = npyv_muladd_s32(a3, b3, c3);
            
            #line 402
            npyv_store_s32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data0, count);
        npyv_s32 b = npyv_load_tillz_s32(data1, count);
        npyv_s32 c = npyv_load_tillz_s32(data_out, count);
        npyv_store_till_s32(data_out, count, npyv_muladd_s32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_int a0 = (data0[0]);
        const npy_int b0 = (data1[0]);
        const npy_int c0 = (data_out[0]);
        
#line 420
        const npy_int a1 = (data0[1]);
        const npy_int b1 = (data1[1]);
        const npy_int c1 = (data_out[1]);
        
#line 420
        const npy_int a2 = (data0[2]);
        const npy_int b2 = (data1[2]);
        const npy_int c2 = (data_out[2]);
        
#line 420
        const npy_int a3 = (data0[3]);
        const npy_int b3 = (data1[3]);
        const npy_int c3 = (data_out[3]);
        
        #line 427
        const npy_int abc0 = a0 * b0 + c0;
        
#line 427
        const npy_int abc1 = a1 * b1 + c1;
        
#line 427
        const npy_int abc2 = a2 * b2 + c2;
        
#line 427
        const npy_int abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_int a = (*data0);
        const npy_int b = (*data1);
        const npy_int c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_int

}

/* Some extra specializations for the two operand case */
static void
int_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int value0 = (*(npy_int *)dataptr[0]);
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data_out = (npy_int *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    int_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
int_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int value1 = (*(npy_int *)dataptr[1]);
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data_out = (npy_int *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    int_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int accum = 0;

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_int
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s32;
    npyv_s32 v_accum = npyv_zero_s32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s32 a0 = npyv_loada_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_loada_s32(data1 + vstep * 0);
            
#line 501
            npyv_s32 a1 = npyv_loada_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_loada_s32(data1 + vstep * 1);
            
#line 501
            npyv_s32 a2 = npyv_loada_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_loada_s32(data1 + vstep * 2);
            
#line 501
            npyv_s32 a3 = npyv_loada_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_loada_s32(data1 + vstep * 3);
            
            npyv_s32 ab3 = npyv_muladd_s32(a3, b3, v_accum);
            npyv_s32 ab2 = npyv_muladd_s32(a2, b2, ab3);
            npyv_s32 ab1 = npyv_muladd_s32(a1, b1, ab2);
                   v_accum = npyv_muladd_s32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s32 a0 = npyv_load_s32(data0 + vstep * 0);
            npyv_s32 b0 = npyv_load_s32(data1 + vstep * 0);
            
#line 501
            npyv_s32 a1 = npyv_load_s32(data0 + vstep * 1);
            npyv_s32 b1 = npyv_load_s32(data1 + vstep * 1);
            
#line 501
            npyv_s32 a2 = npyv_load_s32(data0 + vstep * 2);
            npyv_s32 b2 = npyv_load_s32(data1 + vstep * 2);
            
#line 501
            npyv_s32 a3 = npyv_load_s32(data0 + vstep * 3);
            npyv_s32 b3 = npyv_load_s32(data1 + vstep * 3);
            
            npyv_s32 ab3 = npyv_muladd_s32(a3, b3, v_accum);
            npyv_s32 ab2 = npyv_muladd_s32(a2, b2, ab3);
            npyv_s32 ab1 = npyv_muladd_s32(a1, b1, ab2);
                   v_accum = npyv_muladd_s32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s32 a = npyv_load_tillz_s32(data0, count);
        npyv_s32 b = npyv_load_tillz_s32(data1, count);
        v_accum = npyv_muladd_s32(a, b, v_accum);
    }
    accum = npyv_sum_s32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_int ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_int ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_int ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_int ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_int a = (*data0);
        const npy_int b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_int
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int value0 = (*(npy_int *)dataptr[0]);
    npy_int accum = int_sum_of_arr(data1, count);
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int value1 = (*(npy_int *)dataptr[1]);
    npy_int accum = int_sum_of_arr(data0, count);
    *(npy_int *)dataptr[2] = ((*(npy_int *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
int_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_int *data0 = (npy_int *)dataptr[0];
    npy_int *data1 = (npy_int *)dataptr[1];
    npy_int *data2 = (npy_int *)dataptr[2];
    npy_int *data_out = (npy_int *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
int_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        *(npy_int *)dataptr[nop] = (temp +
                                           (*(npy_int *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_int);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_int *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[0];
        ((npy_int *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_int *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_int);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
int_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_int *data = (npy_int *)dataptr[0];
    npy_int accum = int_sum_of_arr(data, count);
    *((npy_int *)dataptr[1]) = (accum + (*((npy_int *)dataptr[1])));
#else
    npy_int accum_re = 0, accum_im = 0;
    npy_int *data0 = (npy_int *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_int re01 = data0[0] + data0[2];
        const npy_int re23 = data0[4] + data0[6];
        const npy_int im13 = data0[1] + data0[3];
        const npy_int im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_int *)dataptr[1])[0] += accum_re;
    ((npy_int *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
int_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_int accum_re = 0, accum_im = 0;
#else
    npy_int accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("int_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_int *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_int *)data0) *
                 (*(npy_int *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_int *)data0) *
                 (*(npy_int *)data1) *
                 (*(npy_int *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_int temp = (*(npy_int *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_int *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_int *)data0)[0];
        accum_im += ((npy_int *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_int re, im, tmp;
        int i;
        re = ((npy_int *)dataptr[0])[0];
        im = ((npy_int *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_int *)dataptr[i])[0] -
                  im * ((npy_int *)dataptr[i])[1];
            im = re * ((npy_int *)dataptr[i])[1] +
                 im * ((npy_int *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_int *)dataptr[1000])[0] += accum_re;
    ((npy_int *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_int *)dataptr[nop])[0] += accum_re;
    ((npy_int *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_int *)dataptr[1000]) = (accum +
                                    (*((npy_int *)dataptr[1000])));
#  else
    *((npy_int *)dataptr[nop]) = (accum +
                                    (*((npy_int *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_long long_sum_of_arr(npy_long *data, npy_intp count)
{
    npy_long accum = 0;
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_long;
    npyv_long v_accum = npyv_zero_long();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_long a0 = npyv_loada_long(data + vstep * 0);
            
#line 96
            npyv_long a1 = npyv_loada_long(data + vstep * 1);
            
#line 96
            npyv_long a2 = npyv_loada_long(data + vstep * 2);
            
#line 96
            npyv_long a3 = npyv_loada_long(data + vstep * 3);
            
            npyv_long a01   = npyv_add_long(a0, a1);
            npyv_long a23   = npyv_add_long(a2, a3);
            npyv_long a0123 = npyv_add_long(a01, a23);
                     v_accum = npyv_add_long(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_long a0 = npyv_load_long(data + vstep * 0);
            
#line 96
            npyv_long a1 = npyv_load_long(data + vstep * 1);
            
#line 96
            npyv_long a2 = npyv_load_long(data + vstep * 2);
            
#line 96
            npyv_long a3 = npyv_load_long(data + vstep * 3);
            
            npyv_long a01   = npyv_add_long(a0, a1);
            npyv_long a23   = npyv_add_long(a2, a3);
            npyv_long a0123 = npyv_add_long(a01, a23);
                     v_accum = npyv_add_long(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_long a = npyv_load_tillz_long(data, count);
        v_accum = npyv_add_long(a, v_accum);
    }
    accum = npyv_sum_long(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_long a01 = (*data) + (data[1]);
        const npy_long a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_long
    return accum;
}
#endif

#line 131
static void
long_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_long *)data_out = ((*(npy_long *)data0) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_long *)data_out = ((*(npy_long *)data0) *
                                         (*(npy_long *)data1) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_long *)data_out = ((*(npy_long *)data0) *
                                         (*(npy_long *)data1) *
                                         (*(npy_long *)data2) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        *(npy_long *)dataptr[nop] = (temp +
                                           (*(npy_long *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_long *)data_out)[0] = ((npy_long *)data0)[0] +
                                         ((npy_long *)data_out)[0];
        ((npy_long *)data_out)[1] = ((npy_long *)data0)[1] +
                                         ((npy_long *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_long *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[0];
        ((npy_long *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
long_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data_out = (npy_long *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_long *)data_out + 2*6)[0] =
                                    ((npy_long *)data0 + 2*6)[0] +
                                    ((npy_long *)data_out + 2*6)[0];
            ((npy_long *)data_out + 2*6)[1] =
                                    ((npy_long *)data0 + 2*6)[1] +
                                    ((npy_long *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_long *)data_out + 2*5)[0] =
                                    ((npy_long *)data0 + 2*5)[0] +
                                    ((npy_long *)data_out + 2*5)[0];
            ((npy_long *)data_out + 2*5)[1] =
                                    ((npy_long *)data0 + 2*5)[1] +
                                    ((npy_long *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_long *)data_out + 2*4)[0] =
                                    ((npy_long *)data0 + 2*4)[0] +
                                    ((npy_long *)data_out + 2*4)[0];
            ((npy_long *)data_out + 2*4)[1] =
                                    ((npy_long *)data0 + 2*4)[1] +
                                    ((npy_long *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_long *)data_out + 2*3)[0] =
                                    ((npy_long *)data0 + 2*3)[0] +
                                    ((npy_long *)data_out + 2*3)[0];
            ((npy_long *)data_out + 2*3)[1] =
                                    ((npy_long *)data0 + 2*3)[1] +
                                    ((npy_long *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_long *)data_out + 2*2)[0] =
                                    ((npy_long *)data0 + 2*2)[0] +
                                    ((npy_long *)data_out + 2*2)[0];
            ((npy_long *)data_out + 2*2)[1] =
                                    ((npy_long *)data0 + 2*2)[1] +
                                    ((npy_long *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_long *)data_out + 2*1)[0] =
                                    ((npy_long *)data0 + 2*1)[0] +
                                    ((npy_long *)data_out + 2*1)[0];
            ((npy_long *)data_out + 2*1)[1] =
                                    ((npy_long *)data0 + 2*1)[1] +
                                    ((npy_long *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_long *)data_out + 2*0)[0] =
                                    ((npy_long *)data0 + 2*0)[0] +
                                    ((npy_long *)data_out + 2*0)[0];
            ((npy_long *)data_out + 2*0)[1] =
                                    ((npy_long *)data0 + 2*0)[1] +
                                    ((npy_long *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_long *)data_out + 2*0)[0] =
                                ((npy_long *)data0 + 2*0)[0] +
                                ((npy_long *)data_out + 2*0)[0];
        ((npy_long *)data_out + 2*0)[1] =
                                ((npy_long *)data0 + 2*0)[1] +
                                ((npy_long *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_long *)data_out + 2*1)[0] =
                                ((npy_long *)data0 + 2*1)[0] +
                                ((npy_long *)data_out + 2*1)[0];
        ((npy_long *)data_out + 2*1)[1] =
                                ((npy_long *)data0 + 2*1)[1] +
                                ((npy_long *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_long *)data_out + 2*2)[0] =
                                ((npy_long *)data0 + 2*2)[0] +
                                ((npy_long *)data_out + 2*2)[0];
        ((npy_long *)data_out + 2*2)[1] =
                                ((npy_long *)data0 + 2*2)[1] +
                                ((npy_long *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_long *)data_out + 2*3)[0] =
                                ((npy_long *)data0 + 2*3)[0] +
                                ((npy_long *)data_out + 2*3)[0];
        ((npy_long *)data_out + 2*3)[1] =
                                ((npy_long *)data0 + 2*3)[1] +
                                ((npy_long *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_long *)data_out + 2*4)[0] =
                                ((npy_long *)data0 + 2*4)[0] +
                                ((npy_long *)data_out + 2*4)[0];
        ((npy_long *)data_out + 2*4)[1] =
                                ((npy_long *)data0 + 2*4)[1] +
                                ((npy_long *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_long *)data_out + 2*5)[0] =
                                ((npy_long *)data0 + 2*5)[0] +
                                ((npy_long *)data_out + 2*5)[0];
        ((npy_long *)data_out + 2*5)[1] =
                                ((npy_long *)data0 + 2*5)[1] +
                                ((npy_long *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_long *)data_out + 2*6)[0] =
                                ((npy_long *)data0 + 2*6)[0] +
                                ((npy_long *)data_out + 2*6)[0];
        ((npy_long *)data_out + 2*6)[1] =
                                ((npy_long *)data0 + 2*6)[1] +
                                ((npy_long *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_long *)data_out + 2*7)[0] =
                                ((npy_long *)data0 + 2*7)[0] +
                                ((npy_long *)data_out + 2*7)[0];
        ((npy_long *)data_out + 2*7)[1] =
                                ((npy_long *)data0 + 2*7)[1] +
                                ((npy_long *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
long_sum_of_products_muladd(npy_long *data, npy_long *data_out, npy_long scalar, npy_intp count)
{
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_long;
    const npyv_long v_scalar = npyv_setall_long(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_long b0 = npyv_loada_long(data + vstep * 0);
            npyv_long c0 = npyv_loada_long(data_out + vstep * 0);
            
#line 312
            npyv_long b1 = npyv_loada_long(data + vstep * 1);
            npyv_long c1 = npyv_loada_long(data_out + vstep * 1);
            
#line 312
            npyv_long b2 = npyv_loada_long(data + vstep * 2);
            npyv_long c2 = npyv_loada_long(data_out + vstep * 2);
            
#line 312
            npyv_long b3 = npyv_loada_long(data + vstep * 3);
            npyv_long c3 = npyv_loada_long(data_out + vstep * 3);
            
            #line 318
            npyv_long abc0 = npyv_muladd_long(v_scalar, b0, c0);
            
#line 318
            npyv_long abc1 = npyv_muladd_long(v_scalar, b1, c1);
            
#line 318
            npyv_long abc2 = npyv_muladd_long(v_scalar, b2, c2);
            
#line 318
            npyv_long abc3 = npyv_muladd_long(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_long(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_long(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_long(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_long(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_long b0 = npyv_load_long(data + vstep * 0);
            npyv_long c0 = npyv_load_long(data_out + vstep * 0);
            
#line 312
            npyv_long b1 = npyv_load_long(data + vstep * 1);
            npyv_long c1 = npyv_load_long(data_out + vstep * 1);
            
#line 312
            npyv_long b2 = npyv_load_long(data + vstep * 2);
            npyv_long c2 = npyv_load_long(data_out + vstep * 2);
            
#line 312
            npyv_long b3 = npyv_load_long(data + vstep * 3);
            npyv_long c3 = npyv_load_long(data_out + vstep * 3);
            
            #line 318
            npyv_long abc0 = npyv_muladd_long(v_scalar, b0, c0);
            
#line 318
            npyv_long abc1 = npyv_muladd_long(v_scalar, b1, c1);
            
#line 318
            npyv_long abc2 = npyv_muladd_long(v_scalar, b2, c2);
            
#line 318
            npyv_long abc3 = npyv_muladd_long(v_scalar, b3, c3);
            
            #line 323
            npyv_store_long(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_long(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_long(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_long(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_long a = npyv_load_tillz_long(data, count);
        npyv_long b = npyv_load_tillz_long(data_out, count);
        npyv_store_till_long(data_out, count, npyv_muladd_long(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_long b0 = (data[0]);
        const npy_long c0 = (data_out[0]);
        
#line 340
        const npy_long b1 = (data[1]);
        const npy_long c1 = (data_out[1]);
        
#line 340
        const npy_long b2 = (data[2]);
        const npy_long c2 = (data_out[2]);
        
#line 340
        const npy_long b3 = (data[3]);
        const npy_long c3 = (data_out[3]);
        
        #line 346
        const npy_long abc0 = scalar * b0 + c0;
        
#line 346
        const npy_long abc1 = scalar * b1 + c1;
        
#line 346
        const npy_long abc2 = scalar * b2 + c2;
        
#line 346
        const npy_long abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_long b = (*data);
        const npy_long c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_long
}

static void
long_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data_out = (npy_long *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_long
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_long;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_long a0 = npyv_loada_long(data0 + vstep * 0);
            npyv_long b0 = npyv_loada_long(data1 + vstep * 0);
            npyv_long c0 = npyv_loada_long(data_out + vstep * 0);
            
#line 390
            npyv_long a1 = npyv_loada_long(data0 + vstep * 1);
            npyv_long b1 = npyv_loada_long(data1 + vstep * 1);
            npyv_long c1 = npyv_loada_long(data_out + vstep * 1);
            
#line 390
            npyv_long a2 = npyv_loada_long(data0 + vstep * 2);
            npyv_long b2 = npyv_loada_long(data1 + vstep * 2);
            npyv_long c2 = npyv_loada_long(data_out + vstep * 2);
            
#line 390
            npyv_long a3 = npyv_loada_long(data0 + vstep * 3);
            npyv_long b3 = npyv_loada_long(data1 + vstep * 3);
            npyv_long c3 = npyv_loada_long(data_out + vstep * 3);
            
            #line 397
            npyv_long abc0 = npyv_muladd_long(a0, b0, c0);
            
#line 397
            npyv_long abc1 = npyv_muladd_long(a1, b1, c1);
            
#line 397
            npyv_long abc2 = npyv_muladd_long(a2, b2, c2);
            
#line 397
            npyv_long abc3 = npyv_muladd_long(a3, b3, c3);
            
            #line 402
            npyv_storea_long(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_long(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_long(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_long(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_long a0 = npyv_load_long(data0 + vstep * 0);
            npyv_long b0 = npyv_load_long(data1 + vstep * 0);
            npyv_long c0 = npyv_load_long(data_out + vstep * 0);
            
#line 390
            npyv_long a1 = npyv_load_long(data0 + vstep * 1);
            npyv_long b1 = npyv_load_long(data1 + vstep * 1);
            npyv_long c1 = npyv_load_long(data_out + vstep * 1);
            
#line 390
            npyv_long a2 = npyv_load_long(data0 + vstep * 2);
            npyv_long b2 = npyv_load_long(data1 + vstep * 2);
            npyv_long c2 = npyv_load_long(data_out + vstep * 2);
            
#line 390
            npyv_long a3 = npyv_load_long(data0 + vstep * 3);
            npyv_long b3 = npyv_load_long(data1 + vstep * 3);
            npyv_long c3 = npyv_load_long(data_out + vstep * 3);
            
            #line 397
            npyv_long abc0 = npyv_muladd_long(a0, b0, c0);
            
#line 397
            npyv_long abc1 = npyv_muladd_long(a1, b1, c1);
            
#line 397
            npyv_long abc2 = npyv_muladd_long(a2, b2, c2);
            
#line 397
            npyv_long abc3 = npyv_muladd_long(a3, b3, c3);
            
            #line 402
            npyv_store_long(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_long(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_long(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_long(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_long a = npyv_load_tillz_long(data0, count);
        npyv_long b = npyv_load_tillz_long(data1, count);
        npyv_long c = npyv_load_tillz_long(data_out, count);
        npyv_store_till_long(data_out, count, npyv_muladd_long(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_long a0 = (data0[0]);
        const npy_long b0 = (data1[0]);
        const npy_long c0 = (data_out[0]);
        
#line 420
        const npy_long a1 = (data0[1]);
        const npy_long b1 = (data1[1]);
        const npy_long c1 = (data_out[1]);
        
#line 420
        const npy_long a2 = (data0[2]);
        const npy_long b2 = (data1[2]);
        const npy_long c2 = (data_out[2]);
        
#line 420
        const npy_long a3 = (data0[3]);
        const npy_long b3 = (data1[3]);
        const npy_long c3 = (data_out[3]);
        
        #line 427
        const npy_long abc0 = a0 * b0 + c0;
        
#line 427
        const npy_long abc1 = a1 * b1 + c1;
        
#line 427
        const npy_long abc2 = a2 * b2 + c2;
        
#line 427
        const npy_long abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_long a = (*data0);
        const npy_long b = (*data1);
        const npy_long c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_long

}

/* Some extra specializations for the two operand case */
static void
long_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long value0 = (*(npy_long *)dataptr[0]);
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data_out = (npy_long *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    long_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
long_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long value1 = (*(npy_long *)dataptr[1]);
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data_out = (npy_long *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    long_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long accum = 0;

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_long;
    npyv_long v_accum = npyv_zero_long();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_long a0 = npyv_loada_long(data0 + vstep * 0);
            npyv_long b0 = npyv_loada_long(data1 + vstep * 0);
            
#line 501
            npyv_long a1 = npyv_loada_long(data0 + vstep * 1);
            npyv_long b1 = npyv_loada_long(data1 + vstep * 1);
            
#line 501
            npyv_long a2 = npyv_loada_long(data0 + vstep * 2);
            npyv_long b2 = npyv_loada_long(data1 + vstep * 2);
            
#line 501
            npyv_long a3 = npyv_loada_long(data0 + vstep * 3);
            npyv_long b3 = npyv_loada_long(data1 + vstep * 3);
            
            npyv_long ab3 = npyv_muladd_long(a3, b3, v_accum);
            npyv_long ab2 = npyv_muladd_long(a2, b2, ab3);
            npyv_long ab1 = npyv_muladd_long(a1, b1, ab2);
                   v_accum = npyv_muladd_long(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_long a0 = npyv_load_long(data0 + vstep * 0);
            npyv_long b0 = npyv_load_long(data1 + vstep * 0);
            
#line 501
            npyv_long a1 = npyv_load_long(data0 + vstep * 1);
            npyv_long b1 = npyv_load_long(data1 + vstep * 1);
            
#line 501
            npyv_long a2 = npyv_load_long(data0 + vstep * 2);
            npyv_long b2 = npyv_load_long(data1 + vstep * 2);
            
#line 501
            npyv_long a3 = npyv_load_long(data0 + vstep * 3);
            npyv_long b3 = npyv_load_long(data1 + vstep * 3);
            
            npyv_long ab3 = npyv_muladd_long(a3, b3, v_accum);
            npyv_long ab2 = npyv_muladd_long(a2, b2, ab3);
            npyv_long ab1 = npyv_muladd_long(a1, b1, ab2);
                   v_accum = npyv_muladd_long(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_long a = npyv_load_tillz_long(data0, count);
        npyv_long b = npyv_load_tillz_long(data1, count);
        v_accum = npyv_muladd_long(a, b, v_accum);
    }
    accum = npyv_sum_long(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_long ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_long ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_long ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_long ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_long a = (*data0);
        const npy_long b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_long
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long value0 = (*(npy_long *)dataptr[0]);
    npy_long accum = long_sum_of_arr(data1, count);
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long value1 = (*(npy_long *)dataptr[1]);
    npy_long accum = long_sum_of_arr(data0, count);
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
long_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data2 = (npy_long *)dataptr[2];
    npy_long *data_out = (npy_long *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
long_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        *(npy_long *)dataptr[nop] = (temp +
                                           (*(npy_long *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_long);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_long *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[0];
        ((npy_long *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_long);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_long *data = (npy_long *)dataptr[0];
    npy_long accum = long_sum_of_arr(data, count);
    *((npy_long *)dataptr[1]) = (accum + (*((npy_long *)dataptr[1])));
#else
    npy_long accum_re = 0, accum_im = 0;
    npy_long *data0 = (npy_long *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_long re01 = data0[0] + data0[2];
        const npy_long re23 = data0[4] + data0[6];
        const npy_long im13 = data0[1] + data0[3];
        const npy_long im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_long *)dataptr[1])[0] += accum_re;
    ((npy_long *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
long_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_long accum_re = 0, accum_im = 0;
#else
    npy_long accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_long *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_long *)data0) *
                 (*(npy_long *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_long *)data0) *
                 (*(npy_long *)data1) *
                 (*(npy_long *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_long *)data0)[0];
        accum_im += ((npy_long *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_long *)dataptr[1])[0] += accum_re;
    ((npy_long *)dataptr[1])[1] += accum_im;
#  else
    ((npy_long *)dataptr[nop])[0] += accum_re;
    ((npy_long *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_long *)dataptr[1]) = (accum +
                                    (*((npy_long *)dataptr[1])));
#  else
    *((npy_long *)dataptr[nop]) = (accum +
                                    (*((npy_long *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
long_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_long *)data_out = ((*(npy_long *)data0) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_long *)data_out = ((*(npy_long *)data0) *
                                         (*(npy_long *)data1) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_long *)data_out = ((*(npy_long *)data0) *
                                         (*(npy_long *)data1) *
                                         (*(npy_long *)data2) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        *(npy_long *)dataptr[nop] = (temp +
                                           (*(npy_long *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_long *)data_out)[0] = ((npy_long *)data0)[0] +
                                         ((npy_long *)data_out)[0];
        ((npy_long *)data_out)[1] = ((npy_long *)data0)[1] +
                                         ((npy_long *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_long *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[0];
        ((npy_long *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
long_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data_out = (npy_long *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_long *)data_out + 2*6)[0] =
                                    ((npy_long *)data0 + 2*6)[0] +
                                    ((npy_long *)data_out + 2*6)[0];
            ((npy_long *)data_out + 2*6)[1] =
                                    ((npy_long *)data0 + 2*6)[1] +
                                    ((npy_long *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_long *)data_out + 2*5)[0] =
                                    ((npy_long *)data0 + 2*5)[0] +
                                    ((npy_long *)data_out + 2*5)[0];
            ((npy_long *)data_out + 2*5)[1] =
                                    ((npy_long *)data0 + 2*5)[1] +
                                    ((npy_long *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_long *)data_out + 2*4)[0] =
                                    ((npy_long *)data0 + 2*4)[0] +
                                    ((npy_long *)data_out + 2*4)[0];
            ((npy_long *)data_out + 2*4)[1] =
                                    ((npy_long *)data0 + 2*4)[1] +
                                    ((npy_long *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_long *)data_out + 2*3)[0] =
                                    ((npy_long *)data0 + 2*3)[0] +
                                    ((npy_long *)data_out + 2*3)[0];
            ((npy_long *)data_out + 2*3)[1] =
                                    ((npy_long *)data0 + 2*3)[1] +
                                    ((npy_long *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_long *)data_out + 2*2)[0] =
                                    ((npy_long *)data0 + 2*2)[0] +
                                    ((npy_long *)data_out + 2*2)[0];
            ((npy_long *)data_out + 2*2)[1] =
                                    ((npy_long *)data0 + 2*2)[1] +
                                    ((npy_long *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_long *)data_out + 2*1)[0] =
                                    ((npy_long *)data0 + 2*1)[0] +
                                    ((npy_long *)data_out + 2*1)[0];
            ((npy_long *)data_out + 2*1)[1] =
                                    ((npy_long *)data0 + 2*1)[1] +
                                    ((npy_long *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_long *)data_out + 2*0)[0] =
                                    ((npy_long *)data0 + 2*0)[0] +
                                    ((npy_long *)data_out + 2*0)[0];
            ((npy_long *)data_out + 2*0)[1] =
                                    ((npy_long *)data0 + 2*0)[1] +
                                    ((npy_long *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_long *)data_out + 2*0)[0] =
                                ((npy_long *)data0 + 2*0)[0] +
                                ((npy_long *)data_out + 2*0)[0];
        ((npy_long *)data_out + 2*0)[1] =
                                ((npy_long *)data0 + 2*0)[1] +
                                ((npy_long *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_long *)data_out + 2*1)[0] =
                                ((npy_long *)data0 + 2*1)[0] +
                                ((npy_long *)data_out + 2*1)[0];
        ((npy_long *)data_out + 2*1)[1] =
                                ((npy_long *)data0 + 2*1)[1] +
                                ((npy_long *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_long *)data_out + 2*2)[0] =
                                ((npy_long *)data0 + 2*2)[0] +
                                ((npy_long *)data_out + 2*2)[0];
        ((npy_long *)data_out + 2*2)[1] =
                                ((npy_long *)data0 + 2*2)[1] +
                                ((npy_long *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_long *)data_out + 2*3)[0] =
                                ((npy_long *)data0 + 2*3)[0] +
                                ((npy_long *)data_out + 2*3)[0];
        ((npy_long *)data_out + 2*3)[1] =
                                ((npy_long *)data0 + 2*3)[1] +
                                ((npy_long *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_long *)data_out + 2*4)[0] =
                                ((npy_long *)data0 + 2*4)[0] +
                                ((npy_long *)data_out + 2*4)[0];
        ((npy_long *)data_out + 2*4)[1] =
                                ((npy_long *)data0 + 2*4)[1] +
                                ((npy_long *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_long *)data_out + 2*5)[0] =
                                ((npy_long *)data0 + 2*5)[0] +
                                ((npy_long *)data_out + 2*5)[0];
        ((npy_long *)data_out + 2*5)[1] =
                                ((npy_long *)data0 + 2*5)[1] +
                                ((npy_long *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_long *)data_out + 2*6)[0] =
                                ((npy_long *)data0 + 2*6)[0] +
                                ((npy_long *)data_out + 2*6)[0];
        ((npy_long *)data_out + 2*6)[1] =
                                ((npy_long *)data0 + 2*6)[1] +
                                ((npy_long *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_long *)data_out + 2*7)[0] =
                                ((npy_long *)data0 + 2*7)[0] +
                                ((npy_long *)data_out + 2*7)[0];
        ((npy_long *)data_out + 2*7)[1] =
                                ((npy_long *)data0 + 2*7)[1] +
                                ((npy_long *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
long_sum_of_products_muladd(npy_long *data, npy_long *data_out, npy_long scalar, npy_intp count)
{
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_long;
    const npyv_long v_scalar = npyv_setall_long(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_long b0 = npyv_loada_long(data + vstep * 0);
            npyv_long c0 = npyv_loada_long(data_out + vstep * 0);
            
#line 312
            npyv_long b1 = npyv_loada_long(data + vstep * 1);
            npyv_long c1 = npyv_loada_long(data_out + vstep * 1);
            
#line 312
            npyv_long b2 = npyv_loada_long(data + vstep * 2);
            npyv_long c2 = npyv_loada_long(data_out + vstep * 2);
            
#line 312
            npyv_long b3 = npyv_loada_long(data + vstep * 3);
            npyv_long c3 = npyv_loada_long(data_out + vstep * 3);
            
            #line 318
            npyv_long abc0 = npyv_muladd_long(v_scalar, b0, c0);
            
#line 318
            npyv_long abc1 = npyv_muladd_long(v_scalar, b1, c1);
            
#line 318
            npyv_long abc2 = npyv_muladd_long(v_scalar, b2, c2);
            
#line 318
            npyv_long abc3 = npyv_muladd_long(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_long(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_long(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_long(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_long(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_long b0 = npyv_load_long(data + vstep * 0);
            npyv_long c0 = npyv_load_long(data_out + vstep * 0);
            
#line 312
            npyv_long b1 = npyv_load_long(data + vstep * 1);
            npyv_long c1 = npyv_load_long(data_out + vstep * 1);
            
#line 312
            npyv_long b2 = npyv_load_long(data + vstep * 2);
            npyv_long c2 = npyv_load_long(data_out + vstep * 2);
            
#line 312
            npyv_long b3 = npyv_load_long(data + vstep * 3);
            npyv_long c3 = npyv_load_long(data_out + vstep * 3);
            
            #line 318
            npyv_long abc0 = npyv_muladd_long(v_scalar, b0, c0);
            
#line 318
            npyv_long abc1 = npyv_muladd_long(v_scalar, b1, c1);
            
#line 318
            npyv_long abc2 = npyv_muladd_long(v_scalar, b2, c2);
            
#line 318
            npyv_long abc3 = npyv_muladd_long(v_scalar, b3, c3);
            
            #line 323
            npyv_store_long(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_long(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_long(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_long(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_long a = npyv_load_tillz_long(data, count);
        npyv_long b = npyv_load_tillz_long(data_out, count);
        npyv_store_till_long(data_out, count, npyv_muladd_long(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_long b0 = (data[0]);
        const npy_long c0 = (data_out[0]);
        
#line 340
        const npy_long b1 = (data[1]);
        const npy_long c1 = (data_out[1]);
        
#line 340
        const npy_long b2 = (data[2]);
        const npy_long c2 = (data_out[2]);
        
#line 340
        const npy_long b3 = (data[3]);
        const npy_long c3 = (data_out[3]);
        
        #line 346
        const npy_long abc0 = scalar * b0 + c0;
        
#line 346
        const npy_long abc1 = scalar * b1 + c1;
        
#line 346
        const npy_long abc2 = scalar * b2 + c2;
        
#line 346
        const npy_long abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_long b = (*data);
        const npy_long c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_long
}

static void
long_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data_out = (npy_long *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_long
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_long;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_long a0 = npyv_loada_long(data0 + vstep * 0);
            npyv_long b0 = npyv_loada_long(data1 + vstep * 0);
            npyv_long c0 = npyv_loada_long(data_out + vstep * 0);
            
#line 390
            npyv_long a1 = npyv_loada_long(data0 + vstep * 1);
            npyv_long b1 = npyv_loada_long(data1 + vstep * 1);
            npyv_long c1 = npyv_loada_long(data_out + vstep * 1);
            
#line 390
            npyv_long a2 = npyv_loada_long(data0 + vstep * 2);
            npyv_long b2 = npyv_loada_long(data1 + vstep * 2);
            npyv_long c2 = npyv_loada_long(data_out + vstep * 2);
            
#line 390
            npyv_long a3 = npyv_loada_long(data0 + vstep * 3);
            npyv_long b3 = npyv_loada_long(data1 + vstep * 3);
            npyv_long c3 = npyv_loada_long(data_out + vstep * 3);
            
            #line 397
            npyv_long abc0 = npyv_muladd_long(a0, b0, c0);
            
#line 397
            npyv_long abc1 = npyv_muladd_long(a1, b1, c1);
            
#line 397
            npyv_long abc2 = npyv_muladd_long(a2, b2, c2);
            
#line 397
            npyv_long abc3 = npyv_muladd_long(a3, b3, c3);
            
            #line 402
            npyv_storea_long(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_long(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_long(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_long(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_long a0 = npyv_load_long(data0 + vstep * 0);
            npyv_long b0 = npyv_load_long(data1 + vstep * 0);
            npyv_long c0 = npyv_load_long(data_out + vstep * 0);
            
#line 390
            npyv_long a1 = npyv_load_long(data0 + vstep * 1);
            npyv_long b1 = npyv_load_long(data1 + vstep * 1);
            npyv_long c1 = npyv_load_long(data_out + vstep * 1);
            
#line 390
            npyv_long a2 = npyv_load_long(data0 + vstep * 2);
            npyv_long b2 = npyv_load_long(data1 + vstep * 2);
            npyv_long c2 = npyv_load_long(data_out + vstep * 2);
            
#line 390
            npyv_long a3 = npyv_load_long(data0 + vstep * 3);
            npyv_long b3 = npyv_load_long(data1 + vstep * 3);
            npyv_long c3 = npyv_load_long(data_out + vstep * 3);
            
            #line 397
            npyv_long abc0 = npyv_muladd_long(a0, b0, c0);
            
#line 397
            npyv_long abc1 = npyv_muladd_long(a1, b1, c1);
            
#line 397
            npyv_long abc2 = npyv_muladd_long(a2, b2, c2);
            
#line 397
            npyv_long abc3 = npyv_muladd_long(a3, b3, c3);
            
            #line 402
            npyv_store_long(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_long(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_long(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_long(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_long a = npyv_load_tillz_long(data0, count);
        npyv_long b = npyv_load_tillz_long(data1, count);
        npyv_long c = npyv_load_tillz_long(data_out, count);
        npyv_store_till_long(data_out, count, npyv_muladd_long(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_long a0 = (data0[0]);
        const npy_long b0 = (data1[0]);
        const npy_long c0 = (data_out[0]);
        
#line 420
        const npy_long a1 = (data0[1]);
        const npy_long b1 = (data1[1]);
        const npy_long c1 = (data_out[1]);
        
#line 420
        const npy_long a2 = (data0[2]);
        const npy_long b2 = (data1[2]);
        const npy_long c2 = (data_out[2]);
        
#line 420
        const npy_long a3 = (data0[3]);
        const npy_long b3 = (data1[3]);
        const npy_long c3 = (data_out[3]);
        
        #line 427
        const npy_long abc0 = a0 * b0 + c0;
        
#line 427
        const npy_long abc1 = a1 * b1 + c1;
        
#line 427
        const npy_long abc2 = a2 * b2 + c2;
        
#line 427
        const npy_long abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_long a = (*data0);
        const npy_long b = (*data1);
        const npy_long c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_long

}

/* Some extra specializations for the two operand case */
static void
long_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long value0 = (*(npy_long *)dataptr[0]);
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data_out = (npy_long *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    long_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
long_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long value1 = (*(npy_long *)dataptr[1]);
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data_out = (npy_long *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    long_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long accum = 0;

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_long;
    npyv_long v_accum = npyv_zero_long();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_long a0 = npyv_loada_long(data0 + vstep * 0);
            npyv_long b0 = npyv_loada_long(data1 + vstep * 0);
            
#line 501
            npyv_long a1 = npyv_loada_long(data0 + vstep * 1);
            npyv_long b1 = npyv_loada_long(data1 + vstep * 1);
            
#line 501
            npyv_long a2 = npyv_loada_long(data0 + vstep * 2);
            npyv_long b2 = npyv_loada_long(data1 + vstep * 2);
            
#line 501
            npyv_long a3 = npyv_loada_long(data0 + vstep * 3);
            npyv_long b3 = npyv_loada_long(data1 + vstep * 3);
            
            npyv_long ab3 = npyv_muladd_long(a3, b3, v_accum);
            npyv_long ab2 = npyv_muladd_long(a2, b2, ab3);
            npyv_long ab1 = npyv_muladd_long(a1, b1, ab2);
                   v_accum = npyv_muladd_long(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_long a0 = npyv_load_long(data0 + vstep * 0);
            npyv_long b0 = npyv_load_long(data1 + vstep * 0);
            
#line 501
            npyv_long a1 = npyv_load_long(data0 + vstep * 1);
            npyv_long b1 = npyv_load_long(data1 + vstep * 1);
            
#line 501
            npyv_long a2 = npyv_load_long(data0 + vstep * 2);
            npyv_long b2 = npyv_load_long(data1 + vstep * 2);
            
#line 501
            npyv_long a3 = npyv_load_long(data0 + vstep * 3);
            npyv_long b3 = npyv_load_long(data1 + vstep * 3);
            
            npyv_long ab3 = npyv_muladd_long(a3, b3, v_accum);
            npyv_long ab2 = npyv_muladd_long(a2, b2, ab3);
            npyv_long ab1 = npyv_muladd_long(a1, b1, ab2);
                   v_accum = npyv_muladd_long(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_long a = npyv_load_tillz_long(data0, count);
        npyv_long b = npyv_load_tillz_long(data1, count);
        v_accum = npyv_muladd_long(a, b, v_accum);
    }
    accum = npyv_sum_long(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_long ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_long ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_long ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_long ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_long a = (*data0);
        const npy_long b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_long
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long value0 = (*(npy_long *)dataptr[0]);
    npy_long accum = long_sum_of_arr(data1, count);
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long value1 = (*(npy_long *)dataptr[1]);
    npy_long accum = long_sum_of_arr(data0, count);
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
long_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data2 = (npy_long *)dataptr[2];
    npy_long *data_out = (npy_long *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
long_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        *(npy_long *)dataptr[nop] = (temp +
                                           (*(npy_long *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_long);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_long *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[0];
        ((npy_long *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_long);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_long *data = (npy_long *)dataptr[0];
    npy_long accum = long_sum_of_arr(data, count);
    *((npy_long *)dataptr[1]) = (accum + (*((npy_long *)dataptr[1])));
#else
    npy_long accum_re = 0, accum_im = 0;
    npy_long *data0 = (npy_long *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_long re01 = data0[0] + data0[2];
        const npy_long re23 = data0[4] + data0[6];
        const npy_long im13 = data0[1] + data0[3];
        const npy_long im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_long *)dataptr[1])[0] += accum_re;
    ((npy_long *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
long_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_long accum_re = 0, accum_im = 0;
#else
    npy_long accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_long *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_long *)data0) *
                 (*(npy_long *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_long *)data0) *
                 (*(npy_long *)data1) *
                 (*(npy_long *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_long *)data0)[0];
        accum_im += ((npy_long *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_long *)dataptr[2])[0] += accum_re;
    ((npy_long *)dataptr[2])[1] += accum_im;
#  else
    ((npy_long *)dataptr[nop])[0] += accum_re;
    ((npy_long *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_long *)dataptr[2]) = (accum +
                                    (*((npy_long *)dataptr[2])));
#  else
    *((npy_long *)dataptr[nop]) = (accum +
                                    (*((npy_long *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
long_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_long *)data_out = ((*(npy_long *)data0) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_long *)data_out = ((*(npy_long *)data0) *
                                         (*(npy_long *)data1) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_long *)data_out = ((*(npy_long *)data0) *
                                         (*(npy_long *)data1) *
                                         (*(npy_long *)data2) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        *(npy_long *)dataptr[nop] = (temp +
                                           (*(npy_long *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_long *)data_out)[0] = ((npy_long *)data0)[0] +
                                         ((npy_long *)data_out)[0];
        ((npy_long *)data_out)[1] = ((npy_long *)data0)[1] +
                                         ((npy_long *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_long *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[0];
        ((npy_long *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
long_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data_out = (npy_long *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_long *)data_out + 2*6)[0] =
                                    ((npy_long *)data0 + 2*6)[0] +
                                    ((npy_long *)data_out + 2*6)[0];
            ((npy_long *)data_out + 2*6)[1] =
                                    ((npy_long *)data0 + 2*6)[1] +
                                    ((npy_long *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_long *)data_out + 2*5)[0] =
                                    ((npy_long *)data0 + 2*5)[0] +
                                    ((npy_long *)data_out + 2*5)[0];
            ((npy_long *)data_out + 2*5)[1] =
                                    ((npy_long *)data0 + 2*5)[1] +
                                    ((npy_long *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_long *)data_out + 2*4)[0] =
                                    ((npy_long *)data0 + 2*4)[0] +
                                    ((npy_long *)data_out + 2*4)[0];
            ((npy_long *)data_out + 2*4)[1] =
                                    ((npy_long *)data0 + 2*4)[1] +
                                    ((npy_long *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_long *)data_out + 2*3)[0] =
                                    ((npy_long *)data0 + 2*3)[0] +
                                    ((npy_long *)data_out + 2*3)[0];
            ((npy_long *)data_out + 2*3)[1] =
                                    ((npy_long *)data0 + 2*3)[1] +
                                    ((npy_long *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_long *)data_out + 2*2)[0] =
                                    ((npy_long *)data0 + 2*2)[0] +
                                    ((npy_long *)data_out + 2*2)[0];
            ((npy_long *)data_out + 2*2)[1] =
                                    ((npy_long *)data0 + 2*2)[1] +
                                    ((npy_long *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_long *)data_out + 2*1)[0] =
                                    ((npy_long *)data0 + 2*1)[0] +
                                    ((npy_long *)data_out + 2*1)[0];
            ((npy_long *)data_out + 2*1)[1] =
                                    ((npy_long *)data0 + 2*1)[1] +
                                    ((npy_long *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_long *)data_out + 2*0)[0] =
                                    ((npy_long *)data0 + 2*0)[0] +
                                    ((npy_long *)data_out + 2*0)[0];
            ((npy_long *)data_out + 2*0)[1] =
                                    ((npy_long *)data0 + 2*0)[1] +
                                    ((npy_long *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_long *)data_out + 2*0)[0] =
                                ((npy_long *)data0 + 2*0)[0] +
                                ((npy_long *)data_out + 2*0)[0];
        ((npy_long *)data_out + 2*0)[1] =
                                ((npy_long *)data0 + 2*0)[1] +
                                ((npy_long *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_long *)data_out + 2*1)[0] =
                                ((npy_long *)data0 + 2*1)[0] +
                                ((npy_long *)data_out + 2*1)[0];
        ((npy_long *)data_out + 2*1)[1] =
                                ((npy_long *)data0 + 2*1)[1] +
                                ((npy_long *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_long *)data_out + 2*2)[0] =
                                ((npy_long *)data0 + 2*2)[0] +
                                ((npy_long *)data_out + 2*2)[0];
        ((npy_long *)data_out + 2*2)[1] =
                                ((npy_long *)data0 + 2*2)[1] +
                                ((npy_long *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_long *)data_out + 2*3)[0] =
                                ((npy_long *)data0 + 2*3)[0] +
                                ((npy_long *)data_out + 2*3)[0];
        ((npy_long *)data_out + 2*3)[1] =
                                ((npy_long *)data0 + 2*3)[1] +
                                ((npy_long *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_long *)data_out + 2*4)[0] =
                                ((npy_long *)data0 + 2*4)[0] +
                                ((npy_long *)data_out + 2*4)[0];
        ((npy_long *)data_out + 2*4)[1] =
                                ((npy_long *)data0 + 2*4)[1] +
                                ((npy_long *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_long *)data_out + 2*5)[0] =
                                ((npy_long *)data0 + 2*5)[0] +
                                ((npy_long *)data_out + 2*5)[0];
        ((npy_long *)data_out + 2*5)[1] =
                                ((npy_long *)data0 + 2*5)[1] +
                                ((npy_long *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_long *)data_out + 2*6)[0] =
                                ((npy_long *)data0 + 2*6)[0] +
                                ((npy_long *)data_out + 2*6)[0];
        ((npy_long *)data_out + 2*6)[1] =
                                ((npy_long *)data0 + 2*6)[1] +
                                ((npy_long *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_long *)data_out + 2*7)[0] =
                                ((npy_long *)data0 + 2*7)[0] +
                                ((npy_long *)data_out + 2*7)[0];
        ((npy_long *)data_out + 2*7)[1] =
                                ((npy_long *)data0 + 2*7)[1] +
                                ((npy_long *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
long_sum_of_products_muladd(npy_long *data, npy_long *data_out, npy_long scalar, npy_intp count)
{
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_long;
    const npyv_long v_scalar = npyv_setall_long(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_long b0 = npyv_loada_long(data + vstep * 0);
            npyv_long c0 = npyv_loada_long(data_out + vstep * 0);
            
#line 312
            npyv_long b1 = npyv_loada_long(data + vstep * 1);
            npyv_long c1 = npyv_loada_long(data_out + vstep * 1);
            
#line 312
            npyv_long b2 = npyv_loada_long(data + vstep * 2);
            npyv_long c2 = npyv_loada_long(data_out + vstep * 2);
            
#line 312
            npyv_long b3 = npyv_loada_long(data + vstep * 3);
            npyv_long c3 = npyv_loada_long(data_out + vstep * 3);
            
            #line 318
            npyv_long abc0 = npyv_muladd_long(v_scalar, b0, c0);
            
#line 318
            npyv_long abc1 = npyv_muladd_long(v_scalar, b1, c1);
            
#line 318
            npyv_long abc2 = npyv_muladd_long(v_scalar, b2, c2);
            
#line 318
            npyv_long abc3 = npyv_muladd_long(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_long(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_long(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_long(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_long(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_long b0 = npyv_load_long(data + vstep * 0);
            npyv_long c0 = npyv_load_long(data_out + vstep * 0);
            
#line 312
            npyv_long b1 = npyv_load_long(data + vstep * 1);
            npyv_long c1 = npyv_load_long(data_out + vstep * 1);
            
#line 312
            npyv_long b2 = npyv_load_long(data + vstep * 2);
            npyv_long c2 = npyv_load_long(data_out + vstep * 2);
            
#line 312
            npyv_long b3 = npyv_load_long(data + vstep * 3);
            npyv_long c3 = npyv_load_long(data_out + vstep * 3);
            
            #line 318
            npyv_long abc0 = npyv_muladd_long(v_scalar, b0, c0);
            
#line 318
            npyv_long abc1 = npyv_muladd_long(v_scalar, b1, c1);
            
#line 318
            npyv_long abc2 = npyv_muladd_long(v_scalar, b2, c2);
            
#line 318
            npyv_long abc3 = npyv_muladd_long(v_scalar, b3, c3);
            
            #line 323
            npyv_store_long(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_long(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_long(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_long(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_long a = npyv_load_tillz_long(data, count);
        npyv_long b = npyv_load_tillz_long(data_out, count);
        npyv_store_till_long(data_out, count, npyv_muladd_long(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_long b0 = (data[0]);
        const npy_long c0 = (data_out[0]);
        
#line 340
        const npy_long b1 = (data[1]);
        const npy_long c1 = (data_out[1]);
        
#line 340
        const npy_long b2 = (data[2]);
        const npy_long c2 = (data_out[2]);
        
#line 340
        const npy_long b3 = (data[3]);
        const npy_long c3 = (data_out[3]);
        
        #line 346
        const npy_long abc0 = scalar * b0 + c0;
        
#line 346
        const npy_long abc1 = scalar * b1 + c1;
        
#line 346
        const npy_long abc2 = scalar * b2 + c2;
        
#line 346
        const npy_long abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_long b = (*data);
        const npy_long c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_long
}

static void
long_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data_out = (npy_long *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_long
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_long;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_long a0 = npyv_loada_long(data0 + vstep * 0);
            npyv_long b0 = npyv_loada_long(data1 + vstep * 0);
            npyv_long c0 = npyv_loada_long(data_out + vstep * 0);
            
#line 390
            npyv_long a1 = npyv_loada_long(data0 + vstep * 1);
            npyv_long b1 = npyv_loada_long(data1 + vstep * 1);
            npyv_long c1 = npyv_loada_long(data_out + vstep * 1);
            
#line 390
            npyv_long a2 = npyv_loada_long(data0 + vstep * 2);
            npyv_long b2 = npyv_loada_long(data1 + vstep * 2);
            npyv_long c2 = npyv_loada_long(data_out + vstep * 2);
            
#line 390
            npyv_long a3 = npyv_loada_long(data0 + vstep * 3);
            npyv_long b3 = npyv_loada_long(data1 + vstep * 3);
            npyv_long c3 = npyv_loada_long(data_out + vstep * 3);
            
            #line 397
            npyv_long abc0 = npyv_muladd_long(a0, b0, c0);
            
#line 397
            npyv_long abc1 = npyv_muladd_long(a1, b1, c1);
            
#line 397
            npyv_long abc2 = npyv_muladd_long(a2, b2, c2);
            
#line 397
            npyv_long abc3 = npyv_muladd_long(a3, b3, c3);
            
            #line 402
            npyv_storea_long(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_long(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_long(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_long(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_long a0 = npyv_load_long(data0 + vstep * 0);
            npyv_long b0 = npyv_load_long(data1 + vstep * 0);
            npyv_long c0 = npyv_load_long(data_out + vstep * 0);
            
#line 390
            npyv_long a1 = npyv_load_long(data0 + vstep * 1);
            npyv_long b1 = npyv_load_long(data1 + vstep * 1);
            npyv_long c1 = npyv_load_long(data_out + vstep * 1);
            
#line 390
            npyv_long a2 = npyv_load_long(data0 + vstep * 2);
            npyv_long b2 = npyv_load_long(data1 + vstep * 2);
            npyv_long c2 = npyv_load_long(data_out + vstep * 2);
            
#line 390
            npyv_long a3 = npyv_load_long(data0 + vstep * 3);
            npyv_long b3 = npyv_load_long(data1 + vstep * 3);
            npyv_long c3 = npyv_load_long(data_out + vstep * 3);
            
            #line 397
            npyv_long abc0 = npyv_muladd_long(a0, b0, c0);
            
#line 397
            npyv_long abc1 = npyv_muladd_long(a1, b1, c1);
            
#line 397
            npyv_long abc2 = npyv_muladd_long(a2, b2, c2);
            
#line 397
            npyv_long abc3 = npyv_muladd_long(a3, b3, c3);
            
            #line 402
            npyv_store_long(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_long(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_long(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_long(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_long a = npyv_load_tillz_long(data0, count);
        npyv_long b = npyv_load_tillz_long(data1, count);
        npyv_long c = npyv_load_tillz_long(data_out, count);
        npyv_store_till_long(data_out, count, npyv_muladd_long(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_long a0 = (data0[0]);
        const npy_long b0 = (data1[0]);
        const npy_long c0 = (data_out[0]);
        
#line 420
        const npy_long a1 = (data0[1]);
        const npy_long b1 = (data1[1]);
        const npy_long c1 = (data_out[1]);
        
#line 420
        const npy_long a2 = (data0[2]);
        const npy_long b2 = (data1[2]);
        const npy_long c2 = (data_out[2]);
        
#line 420
        const npy_long a3 = (data0[3]);
        const npy_long b3 = (data1[3]);
        const npy_long c3 = (data_out[3]);
        
        #line 427
        const npy_long abc0 = a0 * b0 + c0;
        
#line 427
        const npy_long abc1 = a1 * b1 + c1;
        
#line 427
        const npy_long abc2 = a2 * b2 + c2;
        
#line 427
        const npy_long abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_long a = (*data0);
        const npy_long b = (*data1);
        const npy_long c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_long

}

/* Some extra specializations for the two operand case */
static void
long_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long value0 = (*(npy_long *)dataptr[0]);
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data_out = (npy_long *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    long_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
long_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long value1 = (*(npy_long *)dataptr[1]);
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data_out = (npy_long *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    long_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long accum = 0;

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_long;
    npyv_long v_accum = npyv_zero_long();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_long a0 = npyv_loada_long(data0 + vstep * 0);
            npyv_long b0 = npyv_loada_long(data1 + vstep * 0);
            
#line 501
            npyv_long a1 = npyv_loada_long(data0 + vstep * 1);
            npyv_long b1 = npyv_loada_long(data1 + vstep * 1);
            
#line 501
            npyv_long a2 = npyv_loada_long(data0 + vstep * 2);
            npyv_long b2 = npyv_loada_long(data1 + vstep * 2);
            
#line 501
            npyv_long a3 = npyv_loada_long(data0 + vstep * 3);
            npyv_long b3 = npyv_loada_long(data1 + vstep * 3);
            
            npyv_long ab3 = npyv_muladd_long(a3, b3, v_accum);
            npyv_long ab2 = npyv_muladd_long(a2, b2, ab3);
            npyv_long ab1 = npyv_muladd_long(a1, b1, ab2);
                   v_accum = npyv_muladd_long(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_long a0 = npyv_load_long(data0 + vstep * 0);
            npyv_long b0 = npyv_load_long(data1 + vstep * 0);
            
#line 501
            npyv_long a1 = npyv_load_long(data0 + vstep * 1);
            npyv_long b1 = npyv_load_long(data1 + vstep * 1);
            
#line 501
            npyv_long a2 = npyv_load_long(data0 + vstep * 2);
            npyv_long b2 = npyv_load_long(data1 + vstep * 2);
            
#line 501
            npyv_long a3 = npyv_load_long(data0 + vstep * 3);
            npyv_long b3 = npyv_load_long(data1 + vstep * 3);
            
            npyv_long ab3 = npyv_muladd_long(a3, b3, v_accum);
            npyv_long ab2 = npyv_muladd_long(a2, b2, ab3);
            npyv_long ab1 = npyv_muladd_long(a1, b1, ab2);
                   v_accum = npyv_muladd_long(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_long a = npyv_load_tillz_long(data0, count);
        npyv_long b = npyv_load_tillz_long(data1, count);
        v_accum = npyv_muladd_long(a, b, v_accum);
    }
    accum = npyv_sum_long(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_long ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_long ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_long ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_long ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_long a = (*data0);
        const npy_long b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_long
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long value0 = (*(npy_long *)dataptr[0]);
    npy_long accum = long_sum_of_arr(data1, count);
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long value1 = (*(npy_long *)dataptr[1]);
    npy_long accum = long_sum_of_arr(data0, count);
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
long_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data2 = (npy_long *)dataptr[2];
    npy_long *data_out = (npy_long *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
long_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        *(npy_long *)dataptr[nop] = (temp +
                                           (*(npy_long *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_long);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_long *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[0];
        ((npy_long *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_long);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_long *data = (npy_long *)dataptr[0];
    npy_long accum = long_sum_of_arr(data, count);
    *((npy_long *)dataptr[1]) = (accum + (*((npy_long *)dataptr[1])));
#else
    npy_long accum_re = 0, accum_im = 0;
    npy_long *data0 = (npy_long *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_long re01 = data0[0] + data0[2];
        const npy_long re23 = data0[4] + data0[6];
        const npy_long im13 = data0[1] + data0[3];
        const npy_long im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_long *)dataptr[1])[0] += accum_re;
    ((npy_long *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
long_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_long accum_re = 0, accum_im = 0;
#else
    npy_long accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_long *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_long *)data0) *
                 (*(npy_long *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_long *)data0) *
                 (*(npy_long *)data1) *
                 (*(npy_long *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_long *)data0)[0];
        accum_im += ((npy_long *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_long *)dataptr[3])[0] += accum_re;
    ((npy_long *)dataptr[3])[1] += accum_im;
#  else
    ((npy_long *)dataptr[nop])[0] += accum_re;
    ((npy_long *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_long *)dataptr[3]) = (accum +
                                    (*((npy_long *)dataptr[3])));
#  else
    *((npy_long *)dataptr[nop]) = (accum +
                                    (*((npy_long *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
long_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_long *)data_out = ((*(npy_long *)data0) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_long *)data_out = ((*(npy_long *)data0) *
                                         (*(npy_long *)data1) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_long *)data_out = ((*(npy_long *)data0) *
                                         (*(npy_long *)data1) *
                                         (*(npy_long *)data2) +
                                         (*(npy_long *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        *(npy_long *)dataptr[nop] = (temp +
                                           (*(npy_long *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_long *)data_out)[0] = ((npy_long *)data0)[0] +
                                         ((npy_long *)data_out)[0];
        ((npy_long *)data_out)[1] = ((npy_long *)data0)[1] +
                                         ((npy_long *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_long *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[0];
        ((npy_long *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
long_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data_out = (npy_long *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_long *)data_out + 2*6)[0] =
                                    ((npy_long *)data0 + 2*6)[0] +
                                    ((npy_long *)data_out + 2*6)[0];
            ((npy_long *)data_out + 2*6)[1] =
                                    ((npy_long *)data0 + 2*6)[1] +
                                    ((npy_long *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_long *)data_out + 2*5)[0] =
                                    ((npy_long *)data0 + 2*5)[0] +
                                    ((npy_long *)data_out + 2*5)[0];
            ((npy_long *)data_out + 2*5)[1] =
                                    ((npy_long *)data0 + 2*5)[1] +
                                    ((npy_long *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_long *)data_out + 2*4)[0] =
                                    ((npy_long *)data0 + 2*4)[0] +
                                    ((npy_long *)data_out + 2*4)[0];
            ((npy_long *)data_out + 2*4)[1] =
                                    ((npy_long *)data0 + 2*4)[1] +
                                    ((npy_long *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_long *)data_out + 2*3)[0] =
                                    ((npy_long *)data0 + 2*3)[0] +
                                    ((npy_long *)data_out + 2*3)[0];
            ((npy_long *)data_out + 2*3)[1] =
                                    ((npy_long *)data0 + 2*3)[1] +
                                    ((npy_long *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_long *)data_out + 2*2)[0] =
                                    ((npy_long *)data0 + 2*2)[0] +
                                    ((npy_long *)data_out + 2*2)[0];
            ((npy_long *)data_out + 2*2)[1] =
                                    ((npy_long *)data0 + 2*2)[1] +
                                    ((npy_long *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_long *)data_out + 2*1)[0] =
                                    ((npy_long *)data0 + 2*1)[0] +
                                    ((npy_long *)data_out + 2*1)[0];
            ((npy_long *)data_out + 2*1)[1] =
                                    ((npy_long *)data0 + 2*1)[1] +
                                    ((npy_long *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_long *)data_out + 2*0)[0] =
                                    ((npy_long *)data0 + 2*0)[0] +
                                    ((npy_long *)data_out + 2*0)[0];
            ((npy_long *)data_out + 2*0)[1] =
                                    ((npy_long *)data0 + 2*0)[1] +
                                    ((npy_long *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_long *)data_out + 2*0)[0] =
                                ((npy_long *)data0 + 2*0)[0] +
                                ((npy_long *)data_out + 2*0)[0];
        ((npy_long *)data_out + 2*0)[1] =
                                ((npy_long *)data0 + 2*0)[1] +
                                ((npy_long *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_long *)data_out + 2*1)[0] =
                                ((npy_long *)data0 + 2*1)[0] +
                                ((npy_long *)data_out + 2*1)[0];
        ((npy_long *)data_out + 2*1)[1] =
                                ((npy_long *)data0 + 2*1)[1] +
                                ((npy_long *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_long *)data_out + 2*2)[0] =
                                ((npy_long *)data0 + 2*2)[0] +
                                ((npy_long *)data_out + 2*2)[0];
        ((npy_long *)data_out + 2*2)[1] =
                                ((npy_long *)data0 + 2*2)[1] +
                                ((npy_long *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_long *)data_out + 2*3)[0] =
                                ((npy_long *)data0 + 2*3)[0] +
                                ((npy_long *)data_out + 2*3)[0];
        ((npy_long *)data_out + 2*3)[1] =
                                ((npy_long *)data0 + 2*3)[1] +
                                ((npy_long *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_long *)data_out + 2*4)[0] =
                                ((npy_long *)data0 + 2*4)[0] +
                                ((npy_long *)data_out + 2*4)[0];
        ((npy_long *)data_out + 2*4)[1] =
                                ((npy_long *)data0 + 2*4)[1] +
                                ((npy_long *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_long *)data_out + 2*5)[0] =
                                ((npy_long *)data0 + 2*5)[0] +
                                ((npy_long *)data_out + 2*5)[0];
        ((npy_long *)data_out + 2*5)[1] =
                                ((npy_long *)data0 + 2*5)[1] +
                                ((npy_long *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_long *)data_out + 2*6)[0] =
                                ((npy_long *)data0 + 2*6)[0] +
                                ((npy_long *)data_out + 2*6)[0];
        ((npy_long *)data_out + 2*6)[1] =
                                ((npy_long *)data0 + 2*6)[1] +
                                ((npy_long *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_long *)data_out + 2*7)[0] =
                                ((npy_long *)data0 + 2*7)[0] +
                                ((npy_long *)data_out + 2*7)[0];
        ((npy_long *)data_out + 2*7)[1] =
                                ((npy_long *)data0 + 2*7)[1] +
                                ((npy_long *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
long_sum_of_products_muladd(npy_long *data, npy_long *data_out, npy_long scalar, npy_intp count)
{
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_long;
    const npyv_long v_scalar = npyv_setall_long(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_long b0 = npyv_loada_long(data + vstep * 0);
            npyv_long c0 = npyv_loada_long(data_out + vstep * 0);
            
#line 312
            npyv_long b1 = npyv_loada_long(data + vstep * 1);
            npyv_long c1 = npyv_loada_long(data_out + vstep * 1);
            
#line 312
            npyv_long b2 = npyv_loada_long(data + vstep * 2);
            npyv_long c2 = npyv_loada_long(data_out + vstep * 2);
            
#line 312
            npyv_long b3 = npyv_loada_long(data + vstep * 3);
            npyv_long c3 = npyv_loada_long(data_out + vstep * 3);
            
            #line 318
            npyv_long abc0 = npyv_muladd_long(v_scalar, b0, c0);
            
#line 318
            npyv_long abc1 = npyv_muladd_long(v_scalar, b1, c1);
            
#line 318
            npyv_long abc2 = npyv_muladd_long(v_scalar, b2, c2);
            
#line 318
            npyv_long abc3 = npyv_muladd_long(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_long(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_long(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_long(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_long(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_long b0 = npyv_load_long(data + vstep * 0);
            npyv_long c0 = npyv_load_long(data_out + vstep * 0);
            
#line 312
            npyv_long b1 = npyv_load_long(data + vstep * 1);
            npyv_long c1 = npyv_load_long(data_out + vstep * 1);
            
#line 312
            npyv_long b2 = npyv_load_long(data + vstep * 2);
            npyv_long c2 = npyv_load_long(data_out + vstep * 2);
            
#line 312
            npyv_long b3 = npyv_load_long(data + vstep * 3);
            npyv_long c3 = npyv_load_long(data_out + vstep * 3);
            
            #line 318
            npyv_long abc0 = npyv_muladd_long(v_scalar, b0, c0);
            
#line 318
            npyv_long abc1 = npyv_muladd_long(v_scalar, b1, c1);
            
#line 318
            npyv_long abc2 = npyv_muladd_long(v_scalar, b2, c2);
            
#line 318
            npyv_long abc3 = npyv_muladd_long(v_scalar, b3, c3);
            
            #line 323
            npyv_store_long(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_long(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_long(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_long(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_long a = npyv_load_tillz_long(data, count);
        npyv_long b = npyv_load_tillz_long(data_out, count);
        npyv_store_till_long(data_out, count, npyv_muladd_long(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_long b0 = (data[0]);
        const npy_long c0 = (data_out[0]);
        
#line 340
        const npy_long b1 = (data[1]);
        const npy_long c1 = (data_out[1]);
        
#line 340
        const npy_long b2 = (data[2]);
        const npy_long c2 = (data_out[2]);
        
#line 340
        const npy_long b3 = (data[3]);
        const npy_long c3 = (data_out[3]);
        
        #line 346
        const npy_long abc0 = scalar * b0 + c0;
        
#line 346
        const npy_long abc1 = scalar * b1 + c1;
        
#line 346
        const npy_long abc2 = scalar * b2 + c2;
        
#line 346
        const npy_long abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_long b = (*data);
        const npy_long c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_long
}

static void
long_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data_out = (npy_long *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_long
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_long;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_long a0 = npyv_loada_long(data0 + vstep * 0);
            npyv_long b0 = npyv_loada_long(data1 + vstep * 0);
            npyv_long c0 = npyv_loada_long(data_out + vstep * 0);
            
#line 390
            npyv_long a1 = npyv_loada_long(data0 + vstep * 1);
            npyv_long b1 = npyv_loada_long(data1 + vstep * 1);
            npyv_long c1 = npyv_loada_long(data_out + vstep * 1);
            
#line 390
            npyv_long a2 = npyv_loada_long(data0 + vstep * 2);
            npyv_long b2 = npyv_loada_long(data1 + vstep * 2);
            npyv_long c2 = npyv_loada_long(data_out + vstep * 2);
            
#line 390
            npyv_long a3 = npyv_loada_long(data0 + vstep * 3);
            npyv_long b3 = npyv_loada_long(data1 + vstep * 3);
            npyv_long c3 = npyv_loada_long(data_out + vstep * 3);
            
            #line 397
            npyv_long abc0 = npyv_muladd_long(a0, b0, c0);
            
#line 397
            npyv_long abc1 = npyv_muladd_long(a1, b1, c1);
            
#line 397
            npyv_long abc2 = npyv_muladd_long(a2, b2, c2);
            
#line 397
            npyv_long abc3 = npyv_muladd_long(a3, b3, c3);
            
            #line 402
            npyv_storea_long(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_long(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_long(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_long(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_long a0 = npyv_load_long(data0 + vstep * 0);
            npyv_long b0 = npyv_load_long(data1 + vstep * 0);
            npyv_long c0 = npyv_load_long(data_out + vstep * 0);
            
#line 390
            npyv_long a1 = npyv_load_long(data0 + vstep * 1);
            npyv_long b1 = npyv_load_long(data1 + vstep * 1);
            npyv_long c1 = npyv_load_long(data_out + vstep * 1);
            
#line 390
            npyv_long a2 = npyv_load_long(data0 + vstep * 2);
            npyv_long b2 = npyv_load_long(data1 + vstep * 2);
            npyv_long c2 = npyv_load_long(data_out + vstep * 2);
            
#line 390
            npyv_long a3 = npyv_load_long(data0 + vstep * 3);
            npyv_long b3 = npyv_load_long(data1 + vstep * 3);
            npyv_long c3 = npyv_load_long(data_out + vstep * 3);
            
            #line 397
            npyv_long abc0 = npyv_muladd_long(a0, b0, c0);
            
#line 397
            npyv_long abc1 = npyv_muladd_long(a1, b1, c1);
            
#line 397
            npyv_long abc2 = npyv_muladd_long(a2, b2, c2);
            
#line 397
            npyv_long abc3 = npyv_muladd_long(a3, b3, c3);
            
            #line 402
            npyv_store_long(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_long(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_long(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_long(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_long a = npyv_load_tillz_long(data0, count);
        npyv_long b = npyv_load_tillz_long(data1, count);
        npyv_long c = npyv_load_tillz_long(data_out, count);
        npyv_store_till_long(data_out, count, npyv_muladd_long(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_long a0 = (data0[0]);
        const npy_long b0 = (data1[0]);
        const npy_long c0 = (data_out[0]);
        
#line 420
        const npy_long a1 = (data0[1]);
        const npy_long b1 = (data1[1]);
        const npy_long c1 = (data_out[1]);
        
#line 420
        const npy_long a2 = (data0[2]);
        const npy_long b2 = (data1[2]);
        const npy_long c2 = (data_out[2]);
        
#line 420
        const npy_long a3 = (data0[3]);
        const npy_long b3 = (data1[3]);
        const npy_long c3 = (data_out[3]);
        
        #line 427
        const npy_long abc0 = a0 * b0 + c0;
        
#line 427
        const npy_long abc1 = a1 * b1 + c1;
        
#line 427
        const npy_long abc2 = a2 * b2 + c2;
        
#line 427
        const npy_long abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_long a = (*data0);
        const npy_long b = (*data1);
        const npy_long c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_long

}

/* Some extra specializations for the two operand case */
static void
long_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long value0 = (*(npy_long *)dataptr[0]);
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data_out = (npy_long *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    long_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
long_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long value1 = (*(npy_long *)dataptr[1]);
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data_out = (npy_long *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    long_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long accum = 0;

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_long
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_long;
    npyv_long v_accum = npyv_zero_long();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_long a0 = npyv_loada_long(data0 + vstep * 0);
            npyv_long b0 = npyv_loada_long(data1 + vstep * 0);
            
#line 501
            npyv_long a1 = npyv_loada_long(data0 + vstep * 1);
            npyv_long b1 = npyv_loada_long(data1 + vstep * 1);
            
#line 501
            npyv_long a2 = npyv_loada_long(data0 + vstep * 2);
            npyv_long b2 = npyv_loada_long(data1 + vstep * 2);
            
#line 501
            npyv_long a3 = npyv_loada_long(data0 + vstep * 3);
            npyv_long b3 = npyv_loada_long(data1 + vstep * 3);
            
            npyv_long ab3 = npyv_muladd_long(a3, b3, v_accum);
            npyv_long ab2 = npyv_muladd_long(a2, b2, ab3);
            npyv_long ab1 = npyv_muladd_long(a1, b1, ab2);
                   v_accum = npyv_muladd_long(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_long a0 = npyv_load_long(data0 + vstep * 0);
            npyv_long b0 = npyv_load_long(data1 + vstep * 0);
            
#line 501
            npyv_long a1 = npyv_load_long(data0 + vstep * 1);
            npyv_long b1 = npyv_load_long(data1 + vstep * 1);
            
#line 501
            npyv_long a2 = npyv_load_long(data0 + vstep * 2);
            npyv_long b2 = npyv_load_long(data1 + vstep * 2);
            
#line 501
            npyv_long a3 = npyv_load_long(data0 + vstep * 3);
            npyv_long b3 = npyv_load_long(data1 + vstep * 3);
            
            npyv_long ab3 = npyv_muladd_long(a3, b3, v_accum);
            npyv_long ab2 = npyv_muladd_long(a2, b2, ab3);
            npyv_long ab1 = npyv_muladd_long(a1, b1, ab2);
                   v_accum = npyv_muladd_long(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_long a = npyv_load_tillz_long(data0, count);
        npyv_long b = npyv_load_tillz_long(data1, count);
        v_accum = npyv_muladd_long(a, b, v_accum);
    }
    accum = npyv_sum_long(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_long ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_long ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_long ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_long ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_long a = (*data0);
        const npy_long b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_long
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long value0 = (*(npy_long *)dataptr[0]);
    npy_long accum = long_sum_of_arr(data1, count);
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long value1 = (*(npy_long *)dataptr[1]);
    npy_long accum = long_sum_of_arr(data0, count);
    *(npy_long *)dataptr[2] = ((*(npy_long *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
long_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_long *data0 = (npy_long *)dataptr[0];
    npy_long *data1 = (npy_long *)dataptr[1];
    npy_long *data2 = (npy_long *)dataptr[2];
    npy_long *data_out = (npy_long *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
long_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        *(npy_long *)dataptr[nop] = (temp +
                                           (*(npy_long *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_long);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_long *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[0];
        ((npy_long *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_long *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_long);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
long_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_long *data = (npy_long *)dataptr[0];
    npy_long accum = long_sum_of_arr(data, count);
    *((npy_long *)dataptr[1]) = (accum + (*((npy_long *)dataptr[1])));
#else
    npy_long accum_re = 0, accum_im = 0;
    npy_long *data0 = (npy_long *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_long re01 = data0[0] + data0[2];
        const npy_long re23 = data0[4] + data0[6];
        const npy_long im13 = data0[1] + data0[3];
        const npy_long im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_long *)dataptr[1])[0] += accum_re;
    ((npy_long *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
long_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_long accum_re = 0, accum_im = 0;
#else
    npy_long accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("long_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_long *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_long *)data0) *
                 (*(npy_long *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_long *)data0) *
                 (*(npy_long *)data1) *
                 (*(npy_long *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_long temp = (*(npy_long *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_long *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_long *)data0)[0];
        accum_im += ((npy_long *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_long re, im, tmp;
        int i;
        re = ((npy_long *)dataptr[0])[0];
        im = ((npy_long *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_long *)dataptr[i])[0] -
                  im * ((npy_long *)dataptr[i])[1];
            im = re * ((npy_long *)dataptr[i])[1] +
                 im * ((npy_long *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_long *)dataptr[1000])[0] += accum_re;
    ((npy_long *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_long *)dataptr[nop])[0] += accum_re;
    ((npy_long *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_long *)dataptr[1000]) = (accum +
                                    (*((npy_long *)dataptr[1000])));
#  else
    *((npy_long *)dataptr[nop]) = (accum +
                                    (*((npy_long *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_longlong longlong_sum_of_arr(npy_longlong *data, npy_intp count)
{
    npy_longlong accum = 0;
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_s64;
    npyv_s64 v_accum = npyv_zero_s64();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_s64 a0 = npyv_loada_s64(data + vstep * 0);
            
#line 96
            npyv_s64 a1 = npyv_loada_s64(data + vstep * 1);
            
#line 96
            npyv_s64 a2 = npyv_loada_s64(data + vstep * 2);
            
#line 96
            npyv_s64 a3 = npyv_loada_s64(data + vstep * 3);
            
            npyv_s64 a01   = npyv_add_s64(a0, a1);
            npyv_s64 a23   = npyv_add_s64(a2, a3);
            npyv_s64 a0123 = npyv_add_s64(a01, a23);
                     v_accum = npyv_add_s64(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_s64 a0 = npyv_load_s64(data + vstep * 0);
            
#line 96
            npyv_s64 a1 = npyv_load_s64(data + vstep * 1);
            
#line 96
            npyv_s64 a2 = npyv_load_s64(data + vstep * 2);
            
#line 96
            npyv_s64 a3 = npyv_load_s64(data + vstep * 3);
            
            npyv_s64 a01   = npyv_add_s64(a0, a1);
            npyv_s64 a23   = npyv_add_s64(a2, a3);
            npyv_s64 a0123 = npyv_add_s64(a01, a23);
                     v_accum = npyv_add_s64(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data, count);
        v_accum = npyv_add_s64(a, v_accum);
    }
    accum = npyv_sum_s64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_longlong a01 = (*data) + (data[1]);
        const npy_longlong a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_longlong
    return accum;
}
#endif

#line 131
static void
longlong_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) *
                                         (*(npy_longlong *)data1) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) *
                                         (*(npy_longlong *)data1) *
                                         (*(npy_longlong *)data2) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        *(npy_longlong *)dataptr[nop] = (temp +
                                           (*(npy_longlong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_longlong *)data_out)[0] = ((npy_longlong *)data0)[0] +
                                         ((npy_longlong *)data_out)[0];
        ((npy_longlong *)data_out)[1] = ((npy_longlong *)data0)[1] +
                                         ((npy_longlong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
longlong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data_out = (npy_longlong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longlong *)data_out + 2*6)[0] =
                                    ((npy_longlong *)data0 + 2*6)[0] +
                                    ((npy_longlong *)data_out + 2*6)[0];
            ((npy_longlong *)data_out + 2*6)[1] =
                                    ((npy_longlong *)data0 + 2*6)[1] +
                                    ((npy_longlong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longlong *)data_out + 2*5)[0] =
                                    ((npy_longlong *)data0 + 2*5)[0] +
                                    ((npy_longlong *)data_out + 2*5)[0];
            ((npy_longlong *)data_out + 2*5)[1] =
                                    ((npy_longlong *)data0 + 2*5)[1] +
                                    ((npy_longlong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longlong *)data_out + 2*4)[0] =
                                    ((npy_longlong *)data0 + 2*4)[0] +
                                    ((npy_longlong *)data_out + 2*4)[0];
            ((npy_longlong *)data_out + 2*4)[1] =
                                    ((npy_longlong *)data0 + 2*4)[1] +
                                    ((npy_longlong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longlong *)data_out + 2*3)[0] =
                                    ((npy_longlong *)data0 + 2*3)[0] +
                                    ((npy_longlong *)data_out + 2*3)[0];
            ((npy_longlong *)data_out + 2*3)[1] =
                                    ((npy_longlong *)data0 + 2*3)[1] +
                                    ((npy_longlong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longlong *)data_out + 2*2)[0] =
                                    ((npy_longlong *)data0 + 2*2)[0] +
                                    ((npy_longlong *)data_out + 2*2)[0];
            ((npy_longlong *)data_out + 2*2)[1] =
                                    ((npy_longlong *)data0 + 2*2)[1] +
                                    ((npy_longlong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longlong *)data_out + 2*1)[0] =
                                    ((npy_longlong *)data0 + 2*1)[0] +
                                    ((npy_longlong *)data_out + 2*1)[0];
            ((npy_longlong *)data_out + 2*1)[1] =
                                    ((npy_longlong *)data0 + 2*1)[1] +
                                    ((npy_longlong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longlong *)data_out + 2*0)[0] =
                                    ((npy_longlong *)data0 + 2*0)[0] +
                                    ((npy_longlong *)data_out + 2*0)[0];
            ((npy_longlong *)data_out + 2*0)[1] =
                                    ((npy_longlong *)data0 + 2*0)[1] +
                                    ((npy_longlong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longlong *)data_out + 2*0)[0] =
                                ((npy_longlong *)data0 + 2*0)[0] +
                                ((npy_longlong *)data_out + 2*0)[0];
        ((npy_longlong *)data_out + 2*0)[1] =
                                ((npy_longlong *)data0 + 2*0)[1] +
                                ((npy_longlong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longlong *)data_out + 2*1)[0] =
                                ((npy_longlong *)data0 + 2*1)[0] +
                                ((npy_longlong *)data_out + 2*1)[0];
        ((npy_longlong *)data_out + 2*1)[1] =
                                ((npy_longlong *)data0 + 2*1)[1] +
                                ((npy_longlong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longlong *)data_out + 2*2)[0] =
                                ((npy_longlong *)data0 + 2*2)[0] +
                                ((npy_longlong *)data_out + 2*2)[0];
        ((npy_longlong *)data_out + 2*2)[1] =
                                ((npy_longlong *)data0 + 2*2)[1] +
                                ((npy_longlong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longlong *)data_out + 2*3)[0] =
                                ((npy_longlong *)data0 + 2*3)[0] +
                                ((npy_longlong *)data_out + 2*3)[0];
        ((npy_longlong *)data_out + 2*3)[1] =
                                ((npy_longlong *)data0 + 2*3)[1] +
                                ((npy_longlong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longlong *)data_out + 2*4)[0] =
                                ((npy_longlong *)data0 + 2*4)[0] +
                                ((npy_longlong *)data_out + 2*4)[0];
        ((npy_longlong *)data_out + 2*4)[1] =
                                ((npy_longlong *)data0 + 2*4)[1] +
                                ((npy_longlong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longlong *)data_out + 2*5)[0] =
                                ((npy_longlong *)data0 + 2*5)[0] +
                                ((npy_longlong *)data_out + 2*5)[0];
        ((npy_longlong *)data_out + 2*5)[1] =
                                ((npy_longlong *)data0 + 2*5)[1] +
                                ((npy_longlong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longlong *)data_out + 2*6)[0] =
                                ((npy_longlong *)data0 + 2*6)[0] +
                                ((npy_longlong *)data_out + 2*6)[0];
        ((npy_longlong *)data_out + 2*6)[1] =
                                ((npy_longlong *)data0 + 2*6)[1] +
                                ((npy_longlong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longlong *)data_out + 2*7)[0] =
                                ((npy_longlong *)data0 + 2*7)[0] +
                                ((npy_longlong *)data_out + 2*7)[0];
        ((npy_longlong *)data_out + 2*7)[1] =
                                ((npy_longlong *)data0 + 2*7)[1] +
                                ((npy_longlong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
longlong_sum_of_products_muladd(npy_longlong *data, npy_longlong *data_out, npy_longlong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s64;
    const npyv_s64 v_scalar = npyv_setall_s64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s64 b0 = npyv_loada_s64(data + vstep * 0);
            npyv_s64 c0 = npyv_loada_s64(data_out + vstep * 0);
            
#line 312
            npyv_s64 b1 = npyv_loada_s64(data + vstep * 1);
            npyv_s64 c1 = npyv_loada_s64(data_out + vstep * 1);
            
#line 312
            npyv_s64 b2 = npyv_loada_s64(data + vstep * 2);
            npyv_s64 c2 = npyv_loada_s64(data_out + vstep * 2);
            
#line 312
            npyv_s64 b3 = npyv_loada_s64(data + vstep * 3);
            npyv_s64 c3 = npyv_loada_s64(data_out + vstep * 3);
            
            #line 318
            npyv_s64 abc0 = npyv_muladd_s64(v_scalar, b0, c0);
            
#line 318
            npyv_s64 abc1 = npyv_muladd_s64(v_scalar, b1, c1);
            
#line 318
            npyv_s64 abc2 = npyv_muladd_s64(v_scalar, b2, c2);
            
#line 318
            npyv_s64 abc3 = npyv_muladd_s64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s64 b0 = npyv_load_s64(data + vstep * 0);
            npyv_s64 c0 = npyv_load_s64(data_out + vstep * 0);
            
#line 312
            npyv_s64 b1 = npyv_load_s64(data + vstep * 1);
            npyv_s64 c1 = npyv_load_s64(data_out + vstep * 1);
            
#line 312
            npyv_s64 b2 = npyv_load_s64(data + vstep * 2);
            npyv_s64 c2 = npyv_load_s64(data_out + vstep * 2);
            
#line 312
            npyv_s64 b3 = npyv_load_s64(data + vstep * 3);
            npyv_s64 c3 = npyv_load_s64(data_out + vstep * 3);
            
            #line 318
            npyv_s64 abc0 = npyv_muladd_s64(v_scalar, b0, c0);
            
#line 318
            npyv_s64 abc1 = npyv_muladd_s64(v_scalar, b1, c1);
            
#line 318
            npyv_s64 abc2 = npyv_muladd_s64(v_scalar, b2, c2);
            
#line 318
            npyv_s64 abc3 = npyv_muladd_s64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data, count);
        npyv_s64 b = npyv_load_tillz_s64(data_out, count);
        npyv_store_till_s64(data_out, count, npyv_muladd_s64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longlong b0 = (data[0]);
        const npy_longlong c0 = (data_out[0]);
        
#line 340
        const npy_longlong b1 = (data[1]);
        const npy_longlong c1 = (data_out[1]);
        
#line 340
        const npy_longlong b2 = (data[2]);
        const npy_longlong c2 = (data_out[2]);
        
#line 340
        const npy_longlong b3 = (data[3]);
        const npy_longlong c3 = (data_out[3]);
        
        #line 346
        const npy_longlong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longlong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longlong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longlong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longlong b = (*data);
        const npy_longlong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_longlong
}

static void
longlong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_longlong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s64 a0 = npyv_loada_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_loada_s64(data1 + vstep * 0);
            npyv_s64 c0 = npyv_loada_s64(data_out + vstep * 0);
            
#line 390
            npyv_s64 a1 = npyv_loada_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_loada_s64(data1 + vstep * 1);
            npyv_s64 c1 = npyv_loada_s64(data_out + vstep * 1);
            
#line 390
            npyv_s64 a2 = npyv_loada_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_loada_s64(data1 + vstep * 2);
            npyv_s64 c2 = npyv_loada_s64(data_out + vstep * 2);
            
#line 390
            npyv_s64 a3 = npyv_loada_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_loada_s64(data1 + vstep * 3);
            npyv_s64 c3 = npyv_loada_s64(data_out + vstep * 3);
            
            #line 397
            npyv_s64 abc0 = npyv_muladd_s64(a0, b0, c0);
            
#line 397
            npyv_s64 abc1 = npyv_muladd_s64(a1, b1, c1);
            
#line 397
            npyv_s64 abc2 = npyv_muladd_s64(a2, b2, c2);
            
#line 397
            npyv_s64 abc3 = npyv_muladd_s64(a3, b3, c3);
            
            #line 402
            npyv_storea_s64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s64 a0 = npyv_load_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_load_s64(data1 + vstep * 0);
            npyv_s64 c0 = npyv_load_s64(data_out + vstep * 0);
            
#line 390
            npyv_s64 a1 = npyv_load_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_load_s64(data1 + vstep * 1);
            npyv_s64 c1 = npyv_load_s64(data_out + vstep * 1);
            
#line 390
            npyv_s64 a2 = npyv_load_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_load_s64(data1 + vstep * 2);
            npyv_s64 c2 = npyv_load_s64(data_out + vstep * 2);
            
#line 390
            npyv_s64 a3 = npyv_load_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_load_s64(data1 + vstep * 3);
            npyv_s64 c3 = npyv_load_s64(data_out + vstep * 3);
            
            #line 397
            npyv_s64 abc0 = npyv_muladd_s64(a0, b0, c0);
            
#line 397
            npyv_s64 abc1 = npyv_muladd_s64(a1, b1, c1);
            
#line 397
            npyv_s64 abc2 = npyv_muladd_s64(a2, b2, c2);
            
#line 397
            npyv_s64 abc3 = npyv_muladd_s64(a3, b3, c3);
            
            #line 402
            npyv_store_s64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data0, count);
        npyv_s64 b = npyv_load_tillz_s64(data1, count);
        npyv_s64 c = npyv_load_tillz_s64(data_out, count);
        npyv_store_till_s64(data_out, count, npyv_muladd_s64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longlong a0 = (data0[0]);
        const npy_longlong b0 = (data1[0]);
        const npy_longlong c0 = (data_out[0]);
        
#line 420
        const npy_longlong a1 = (data0[1]);
        const npy_longlong b1 = (data1[1]);
        const npy_longlong c1 = (data_out[1]);
        
#line 420
        const npy_longlong a2 = (data0[2]);
        const npy_longlong b2 = (data1[2]);
        const npy_longlong c2 = (data_out[2]);
        
#line 420
        const npy_longlong a3 = (data0[3]);
        const npy_longlong b3 = (data1[3]);
        const npy_longlong c3 = (data_out[3]);
        
        #line 427
        const npy_longlong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longlong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longlong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longlong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longlong a = (*data0);
        const npy_longlong b = (*data1);
        const npy_longlong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_longlong

}

/* Some extra specializations for the two operand case */
static void
longlong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong value0 = (*(npy_longlong *)dataptr[0]);
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    longlong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
longlong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong value1 = (*(npy_longlong *)dataptr[1]);
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    longlong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong accum = 0;

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s64;
    npyv_s64 v_accum = npyv_zero_s64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s64 a0 = npyv_loada_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_loada_s64(data1 + vstep * 0);
            
#line 501
            npyv_s64 a1 = npyv_loada_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_loada_s64(data1 + vstep * 1);
            
#line 501
            npyv_s64 a2 = npyv_loada_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_loada_s64(data1 + vstep * 2);
            
#line 501
            npyv_s64 a3 = npyv_loada_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_loada_s64(data1 + vstep * 3);
            
            npyv_s64 ab3 = npyv_muladd_s64(a3, b3, v_accum);
            npyv_s64 ab2 = npyv_muladd_s64(a2, b2, ab3);
            npyv_s64 ab1 = npyv_muladd_s64(a1, b1, ab2);
                   v_accum = npyv_muladd_s64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s64 a0 = npyv_load_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_load_s64(data1 + vstep * 0);
            
#line 501
            npyv_s64 a1 = npyv_load_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_load_s64(data1 + vstep * 1);
            
#line 501
            npyv_s64 a2 = npyv_load_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_load_s64(data1 + vstep * 2);
            
#line 501
            npyv_s64 a3 = npyv_load_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_load_s64(data1 + vstep * 3);
            
            npyv_s64 ab3 = npyv_muladd_s64(a3, b3, v_accum);
            npyv_s64 ab2 = npyv_muladd_s64(a2, b2, ab3);
            npyv_s64 ab1 = npyv_muladd_s64(a1, b1, ab2);
                   v_accum = npyv_muladd_s64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data0, count);
        npyv_s64 b = npyv_load_tillz_s64(data1, count);
        v_accum = npyv_muladd_s64(a, b, v_accum);
    }
    accum = npyv_sum_s64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longlong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longlong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longlong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longlong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longlong a = (*data0);
        const npy_longlong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_longlong
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong value0 = (*(npy_longlong *)dataptr[0]);
    npy_longlong accum = longlong_sum_of_arr(data1, count);
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong value1 = (*(npy_longlong *)dataptr[1]);
    npy_longlong accum = longlong_sum_of_arr(data0, count);
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
longlong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data2 = (npy_longlong *)dataptr[2];
    npy_longlong *data_out = (npy_longlong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
longlong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        *(npy_longlong *)dataptr[nop] = (temp +
                                           (*(npy_longlong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_longlong);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_longlong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_longlong *data = (npy_longlong *)dataptr[0];
    npy_longlong accum = longlong_sum_of_arr(data, count);
    *((npy_longlong *)dataptr[1]) = (accum + (*((npy_longlong *)dataptr[1])));
#else
    npy_longlong accum_re = 0, accum_im = 0;
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longlong re01 = data0[0] + data0[2];
        const npy_longlong re23 = data0[4] + data0[6];
        const npy_longlong im13 = data0[1] + data0[3];
        const npy_longlong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longlong *)dataptr[1])[0] += accum_re;
    ((npy_longlong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
longlong_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_longlong accum_re = 0, accum_im = 0;
#else
    npy_longlong accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_longlong *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_longlong *)data0) *
                 (*(npy_longlong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_longlong *)data0) *
                 (*(npy_longlong *)data1) *
                 (*(npy_longlong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_longlong *)data0)[0];
        accum_im += ((npy_longlong *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_longlong *)dataptr[1])[0] += accum_re;
    ((npy_longlong *)dataptr[1])[1] += accum_im;
#  else
    ((npy_longlong *)dataptr[nop])[0] += accum_re;
    ((npy_longlong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_longlong *)dataptr[1]) = (accum +
                                    (*((npy_longlong *)dataptr[1])));
#  else
    *((npy_longlong *)dataptr[nop]) = (accum +
                                    (*((npy_longlong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
longlong_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) *
                                         (*(npy_longlong *)data1) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) *
                                         (*(npy_longlong *)data1) *
                                         (*(npy_longlong *)data2) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        *(npy_longlong *)dataptr[nop] = (temp +
                                           (*(npy_longlong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_longlong *)data_out)[0] = ((npy_longlong *)data0)[0] +
                                         ((npy_longlong *)data_out)[0];
        ((npy_longlong *)data_out)[1] = ((npy_longlong *)data0)[1] +
                                         ((npy_longlong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
longlong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data_out = (npy_longlong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longlong *)data_out + 2*6)[0] =
                                    ((npy_longlong *)data0 + 2*6)[0] +
                                    ((npy_longlong *)data_out + 2*6)[0];
            ((npy_longlong *)data_out + 2*6)[1] =
                                    ((npy_longlong *)data0 + 2*6)[1] +
                                    ((npy_longlong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longlong *)data_out + 2*5)[0] =
                                    ((npy_longlong *)data0 + 2*5)[0] +
                                    ((npy_longlong *)data_out + 2*5)[0];
            ((npy_longlong *)data_out + 2*5)[1] =
                                    ((npy_longlong *)data0 + 2*5)[1] +
                                    ((npy_longlong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longlong *)data_out + 2*4)[0] =
                                    ((npy_longlong *)data0 + 2*4)[0] +
                                    ((npy_longlong *)data_out + 2*4)[0];
            ((npy_longlong *)data_out + 2*4)[1] =
                                    ((npy_longlong *)data0 + 2*4)[1] +
                                    ((npy_longlong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longlong *)data_out + 2*3)[0] =
                                    ((npy_longlong *)data0 + 2*3)[0] +
                                    ((npy_longlong *)data_out + 2*3)[0];
            ((npy_longlong *)data_out + 2*3)[1] =
                                    ((npy_longlong *)data0 + 2*3)[1] +
                                    ((npy_longlong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longlong *)data_out + 2*2)[0] =
                                    ((npy_longlong *)data0 + 2*2)[0] +
                                    ((npy_longlong *)data_out + 2*2)[0];
            ((npy_longlong *)data_out + 2*2)[1] =
                                    ((npy_longlong *)data0 + 2*2)[1] +
                                    ((npy_longlong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longlong *)data_out + 2*1)[0] =
                                    ((npy_longlong *)data0 + 2*1)[0] +
                                    ((npy_longlong *)data_out + 2*1)[0];
            ((npy_longlong *)data_out + 2*1)[1] =
                                    ((npy_longlong *)data0 + 2*1)[1] +
                                    ((npy_longlong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longlong *)data_out + 2*0)[0] =
                                    ((npy_longlong *)data0 + 2*0)[0] +
                                    ((npy_longlong *)data_out + 2*0)[0];
            ((npy_longlong *)data_out + 2*0)[1] =
                                    ((npy_longlong *)data0 + 2*0)[1] +
                                    ((npy_longlong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longlong *)data_out + 2*0)[0] =
                                ((npy_longlong *)data0 + 2*0)[0] +
                                ((npy_longlong *)data_out + 2*0)[0];
        ((npy_longlong *)data_out + 2*0)[1] =
                                ((npy_longlong *)data0 + 2*0)[1] +
                                ((npy_longlong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longlong *)data_out + 2*1)[0] =
                                ((npy_longlong *)data0 + 2*1)[0] +
                                ((npy_longlong *)data_out + 2*1)[0];
        ((npy_longlong *)data_out + 2*1)[1] =
                                ((npy_longlong *)data0 + 2*1)[1] +
                                ((npy_longlong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longlong *)data_out + 2*2)[0] =
                                ((npy_longlong *)data0 + 2*2)[0] +
                                ((npy_longlong *)data_out + 2*2)[0];
        ((npy_longlong *)data_out + 2*2)[1] =
                                ((npy_longlong *)data0 + 2*2)[1] +
                                ((npy_longlong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longlong *)data_out + 2*3)[0] =
                                ((npy_longlong *)data0 + 2*3)[0] +
                                ((npy_longlong *)data_out + 2*3)[0];
        ((npy_longlong *)data_out + 2*3)[1] =
                                ((npy_longlong *)data0 + 2*3)[1] +
                                ((npy_longlong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longlong *)data_out + 2*4)[0] =
                                ((npy_longlong *)data0 + 2*4)[0] +
                                ((npy_longlong *)data_out + 2*4)[0];
        ((npy_longlong *)data_out + 2*4)[1] =
                                ((npy_longlong *)data0 + 2*4)[1] +
                                ((npy_longlong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longlong *)data_out + 2*5)[0] =
                                ((npy_longlong *)data0 + 2*5)[0] +
                                ((npy_longlong *)data_out + 2*5)[0];
        ((npy_longlong *)data_out + 2*5)[1] =
                                ((npy_longlong *)data0 + 2*5)[1] +
                                ((npy_longlong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longlong *)data_out + 2*6)[0] =
                                ((npy_longlong *)data0 + 2*6)[0] +
                                ((npy_longlong *)data_out + 2*6)[0];
        ((npy_longlong *)data_out + 2*6)[1] =
                                ((npy_longlong *)data0 + 2*6)[1] +
                                ((npy_longlong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longlong *)data_out + 2*7)[0] =
                                ((npy_longlong *)data0 + 2*7)[0] +
                                ((npy_longlong *)data_out + 2*7)[0];
        ((npy_longlong *)data_out + 2*7)[1] =
                                ((npy_longlong *)data0 + 2*7)[1] +
                                ((npy_longlong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
longlong_sum_of_products_muladd(npy_longlong *data, npy_longlong *data_out, npy_longlong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s64;
    const npyv_s64 v_scalar = npyv_setall_s64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s64 b0 = npyv_loada_s64(data + vstep * 0);
            npyv_s64 c0 = npyv_loada_s64(data_out + vstep * 0);
            
#line 312
            npyv_s64 b1 = npyv_loada_s64(data + vstep * 1);
            npyv_s64 c1 = npyv_loada_s64(data_out + vstep * 1);
            
#line 312
            npyv_s64 b2 = npyv_loada_s64(data + vstep * 2);
            npyv_s64 c2 = npyv_loada_s64(data_out + vstep * 2);
            
#line 312
            npyv_s64 b3 = npyv_loada_s64(data + vstep * 3);
            npyv_s64 c3 = npyv_loada_s64(data_out + vstep * 3);
            
            #line 318
            npyv_s64 abc0 = npyv_muladd_s64(v_scalar, b0, c0);
            
#line 318
            npyv_s64 abc1 = npyv_muladd_s64(v_scalar, b1, c1);
            
#line 318
            npyv_s64 abc2 = npyv_muladd_s64(v_scalar, b2, c2);
            
#line 318
            npyv_s64 abc3 = npyv_muladd_s64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s64 b0 = npyv_load_s64(data + vstep * 0);
            npyv_s64 c0 = npyv_load_s64(data_out + vstep * 0);
            
#line 312
            npyv_s64 b1 = npyv_load_s64(data + vstep * 1);
            npyv_s64 c1 = npyv_load_s64(data_out + vstep * 1);
            
#line 312
            npyv_s64 b2 = npyv_load_s64(data + vstep * 2);
            npyv_s64 c2 = npyv_load_s64(data_out + vstep * 2);
            
#line 312
            npyv_s64 b3 = npyv_load_s64(data + vstep * 3);
            npyv_s64 c3 = npyv_load_s64(data_out + vstep * 3);
            
            #line 318
            npyv_s64 abc0 = npyv_muladd_s64(v_scalar, b0, c0);
            
#line 318
            npyv_s64 abc1 = npyv_muladd_s64(v_scalar, b1, c1);
            
#line 318
            npyv_s64 abc2 = npyv_muladd_s64(v_scalar, b2, c2);
            
#line 318
            npyv_s64 abc3 = npyv_muladd_s64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data, count);
        npyv_s64 b = npyv_load_tillz_s64(data_out, count);
        npyv_store_till_s64(data_out, count, npyv_muladd_s64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longlong b0 = (data[0]);
        const npy_longlong c0 = (data_out[0]);
        
#line 340
        const npy_longlong b1 = (data[1]);
        const npy_longlong c1 = (data_out[1]);
        
#line 340
        const npy_longlong b2 = (data[2]);
        const npy_longlong c2 = (data_out[2]);
        
#line 340
        const npy_longlong b3 = (data[3]);
        const npy_longlong c3 = (data_out[3]);
        
        #line 346
        const npy_longlong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longlong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longlong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longlong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longlong b = (*data);
        const npy_longlong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_longlong
}

static void
longlong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_longlong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s64 a0 = npyv_loada_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_loada_s64(data1 + vstep * 0);
            npyv_s64 c0 = npyv_loada_s64(data_out + vstep * 0);
            
#line 390
            npyv_s64 a1 = npyv_loada_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_loada_s64(data1 + vstep * 1);
            npyv_s64 c1 = npyv_loada_s64(data_out + vstep * 1);
            
#line 390
            npyv_s64 a2 = npyv_loada_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_loada_s64(data1 + vstep * 2);
            npyv_s64 c2 = npyv_loada_s64(data_out + vstep * 2);
            
#line 390
            npyv_s64 a3 = npyv_loada_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_loada_s64(data1 + vstep * 3);
            npyv_s64 c3 = npyv_loada_s64(data_out + vstep * 3);
            
            #line 397
            npyv_s64 abc0 = npyv_muladd_s64(a0, b0, c0);
            
#line 397
            npyv_s64 abc1 = npyv_muladd_s64(a1, b1, c1);
            
#line 397
            npyv_s64 abc2 = npyv_muladd_s64(a2, b2, c2);
            
#line 397
            npyv_s64 abc3 = npyv_muladd_s64(a3, b3, c3);
            
            #line 402
            npyv_storea_s64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s64 a0 = npyv_load_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_load_s64(data1 + vstep * 0);
            npyv_s64 c0 = npyv_load_s64(data_out + vstep * 0);
            
#line 390
            npyv_s64 a1 = npyv_load_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_load_s64(data1 + vstep * 1);
            npyv_s64 c1 = npyv_load_s64(data_out + vstep * 1);
            
#line 390
            npyv_s64 a2 = npyv_load_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_load_s64(data1 + vstep * 2);
            npyv_s64 c2 = npyv_load_s64(data_out + vstep * 2);
            
#line 390
            npyv_s64 a3 = npyv_load_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_load_s64(data1 + vstep * 3);
            npyv_s64 c3 = npyv_load_s64(data_out + vstep * 3);
            
            #line 397
            npyv_s64 abc0 = npyv_muladd_s64(a0, b0, c0);
            
#line 397
            npyv_s64 abc1 = npyv_muladd_s64(a1, b1, c1);
            
#line 397
            npyv_s64 abc2 = npyv_muladd_s64(a2, b2, c2);
            
#line 397
            npyv_s64 abc3 = npyv_muladd_s64(a3, b3, c3);
            
            #line 402
            npyv_store_s64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data0, count);
        npyv_s64 b = npyv_load_tillz_s64(data1, count);
        npyv_s64 c = npyv_load_tillz_s64(data_out, count);
        npyv_store_till_s64(data_out, count, npyv_muladd_s64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longlong a0 = (data0[0]);
        const npy_longlong b0 = (data1[0]);
        const npy_longlong c0 = (data_out[0]);
        
#line 420
        const npy_longlong a1 = (data0[1]);
        const npy_longlong b1 = (data1[1]);
        const npy_longlong c1 = (data_out[1]);
        
#line 420
        const npy_longlong a2 = (data0[2]);
        const npy_longlong b2 = (data1[2]);
        const npy_longlong c2 = (data_out[2]);
        
#line 420
        const npy_longlong a3 = (data0[3]);
        const npy_longlong b3 = (data1[3]);
        const npy_longlong c3 = (data_out[3]);
        
        #line 427
        const npy_longlong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longlong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longlong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longlong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longlong a = (*data0);
        const npy_longlong b = (*data1);
        const npy_longlong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_longlong

}

/* Some extra specializations for the two operand case */
static void
longlong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong value0 = (*(npy_longlong *)dataptr[0]);
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    longlong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
longlong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong value1 = (*(npy_longlong *)dataptr[1]);
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    longlong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong accum = 0;

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s64;
    npyv_s64 v_accum = npyv_zero_s64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s64 a0 = npyv_loada_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_loada_s64(data1 + vstep * 0);
            
#line 501
            npyv_s64 a1 = npyv_loada_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_loada_s64(data1 + vstep * 1);
            
#line 501
            npyv_s64 a2 = npyv_loada_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_loada_s64(data1 + vstep * 2);
            
#line 501
            npyv_s64 a3 = npyv_loada_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_loada_s64(data1 + vstep * 3);
            
            npyv_s64 ab3 = npyv_muladd_s64(a3, b3, v_accum);
            npyv_s64 ab2 = npyv_muladd_s64(a2, b2, ab3);
            npyv_s64 ab1 = npyv_muladd_s64(a1, b1, ab2);
                   v_accum = npyv_muladd_s64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s64 a0 = npyv_load_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_load_s64(data1 + vstep * 0);
            
#line 501
            npyv_s64 a1 = npyv_load_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_load_s64(data1 + vstep * 1);
            
#line 501
            npyv_s64 a2 = npyv_load_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_load_s64(data1 + vstep * 2);
            
#line 501
            npyv_s64 a3 = npyv_load_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_load_s64(data1 + vstep * 3);
            
            npyv_s64 ab3 = npyv_muladd_s64(a3, b3, v_accum);
            npyv_s64 ab2 = npyv_muladd_s64(a2, b2, ab3);
            npyv_s64 ab1 = npyv_muladd_s64(a1, b1, ab2);
                   v_accum = npyv_muladd_s64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data0, count);
        npyv_s64 b = npyv_load_tillz_s64(data1, count);
        v_accum = npyv_muladd_s64(a, b, v_accum);
    }
    accum = npyv_sum_s64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longlong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longlong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longlong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longlong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longlong a = (*data0);
        const npy_longlong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_longlong
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong value0 = (*(npy_longlong *)dataptr[0]);
    npy_longlong accum = longlong_sum_of_arr(data1, count);
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong value1 = (*(npy_longlong *)dataptr[1]);
    npy_longlong accum = longlong_sum_of_arr(data0, count);
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
longlong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data2 = (npy_longlong *)dataptr[2];
    npy_longlong *data_out = (npy_longlong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
longlong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        *(npy_longlong *)dataptr[nop] = (temp +
                                           (*(npy_longlong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_longlong);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_longlong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_longlong *data = (npy_longlong *)dataptr[0];
    npy_longlong accum = longlong_sum_of_arr(data, count);
    *((npy_longlong *)dataptr[1]) = (accum + (*((npy_longlong *)dataptr[1])));
#else
    npy_longlong accum_re = 0, accum_im = 0;
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longlong re01 = data0[0] + data0[2];
        const npy_longlong re23 = data0[4] + data0[6];
        const npy_longlong im13 = data0[1] + data0[3];
        const npy_longlong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longlong *)dataptr[1])[0] += accum_re;
    ((npy_longlong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
longlong_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_longlong accum_re = 0, accum_im = 0;
#else
    npy_longlong accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_longlong *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_longlong *)data0) *
                 (*(npy_longlong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_longlong *)data0) *
                 (*(npy_longlong *)data1) *
                 (*(npy_longlong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_longlong *)data0)[0];
        accum_im += ((npy_longlong *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_longlong *)dataptr[2])[0] += accum_re;
    ((npy_longlong *)dataptr[2])[1] += accum_im;
#  else
    ((npy_longlong *)dataptr[nop])[0] += accum_re;
    ((npy_longlong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_longlong *)dataptr[2]) = (accum +
                                    (*((npy_longlong *)dataptr[2])));
#  else
    *((npy_longlong *)dataptr[nop]) = (accum +
                                    (*((npy_longlong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
longlong_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) *
                                         (*(npy_longlong *)data1) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) *
                                         (*(npy_longlong *)data1) *
                                         (*(npy_longlong *)data2) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        *(npy_longlong *)dataptr[nop] = (temp +
                                           (*(npy_longlong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_longlong *)data_out)[0] = ((npy_longlong *)data0)[0] +
                                         ((npy_longlong *)data_out)[0];
        ((npy_longlong *)data_out)[1] = ((npy_longlong *)data0)[1] +
                                         ((npy_longlong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
longlong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data_out = (npy_longlong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longlong *)data_out + 2*6)[0] =
                                    ((npy_longlong *)data0 + 2*6)[0] +
                                    ((npy_longlong *)data_out + 2*6)[0];
            ((npy_longlong *)data_out + 2*6)[1] =
                                    ((npy_longlong *)data0 + 2*6)[1] +
                                    ((npy_longlong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longlong *)data_out + 2*5)[0] =
                                    ((npy_longlong *)data0 + 2*5)[0] +
                                    ((npy_longlong *)data_out + 2*5)[0];
            ((npy_longlong *)data_out + 2*5)[1] =
                                    ((npy_longlong *)data0 + 2*5)[1] +
                                    ((npy_longlong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longlong *)data_out + 2*4)[0] =
                                    ((npy_longlong *)data0 + 2*4)[0] +
                                    ((npy_longlong *)data_out + 2*4)[0];
            ((npy_longlong *)data_out + 2*4)[1] =
                                    ((npy_longlong *)data0 + 2*4)[1] +
                                    ((npy_longlong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longlong *)data_out + 2*3)[0] =
                                    ((npy_longlong *)data0 + 2*3)[0] +
                                    ((npy_longlong *)data_out + 2*3)[0];
            ((npy_longlong *)data_out + 2*3)[1] =
                                    ((npy_longlong *)data0 + 2*3)[1] +
                                    ((npy_longlong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longlong *)data_out + 2*2)[0] =
                                    ((npy_longlong *)data0 + 2*2)[0] +
                                    ((npy_longlong *)data_out + 2*2)[0];
            ((npy_longlong *)data_out + 2*2)[1] =
                                    ((npy_longlong *)data0 + 2*2)[1] +
                                    ((npy_longlong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longlong *)data_out + 2*1)[0] =
                                    ((npy_longlong *)data0 + 2*1)[0] +
                                    ((npy_longlong *)data_out + 2*1)[0];
            ((npy_longlong *)data_out + 2*1)[1] =
                                    ((npy_longlong *)data0 + 2*1)[1] +
                                    ((npy_longlong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longlong *)data_out + 2*0)[0] =
                                    ((npy_longlong *)data0 + 2*0)[0] +
                                    ((npy_longlong *)data_out + 2*0)[0];
            ((npy_longlong *)data_out + 2*0)[1] =
                                    ((npy_longlong *)data0 + 2*0)[1] +
                                    ((npy_longlong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longlong *)data_out + 2*0)[0] =
                                ((npy_longlong *)data0 + 2*0)[0] +
                                ((npy_longlong *)data_out + 2*0)[0];
        ((npy_longlong *)data_out + 2*0)[1] =
                                ((npy_longlong *)data0 + 2*0)[1] +
                                ((npy_longlong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longlong *)data_out + 2*1)[0] =
                                ((npy_longlong *)data0 + 2*1)[0] +
                                ((npy_longlong *)data_out + 2*1)[0];
        ((npy_longlong *)data_out + 2*1)[1] =
                                ((npy_longlong *)data0 + 2*1)[1] +
                                ((npy_longlong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longlong *)data_out + 2*2)[0] =
                                ((npy_longlong *)data0 + 2*2)[0] +
                                ((npy_longlong *)data_out + 2*2)[0];
        ((npy_longlong *)data_out + 2*2)[1] =
                                ((npy_longlong *)data0 + 2*2)[1] +
                                ((npy_longlong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longlong *)data_out + 2*3)[0] =
                                ((npy_longlong *)data0 + 2*3)[0] +
                                ((npy_longlong *)data_out + 2*3)[0];
        ((npy_longlong *)data_out + 2*3)[1] =
                                ((npy_longlong *)data0 + 2*3)[1] +
                                ((npy_longlong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longlong *)data_out + 2*4)[0] =
                                ((npy_longlong *)data0 + 2*4)[0] +
                                ((npy_longlong *)data_out + 2*4)[0];
        ((npy_longlong *)data_out + 2*4)[1] =
                                ((npy_longlong *)data0 + 2*4)[1] +
                                ((npy_longlong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longlong *)data_out + 2*5)[0] =
                                ((npy_longlong *)data0 + 2*5)[0] +
                                ((npy_longlong *)data_out + 2*5)[0];
        ((npy_longlong *)data_out + 2*5)[1] =
                                ((npy_longlong *)data0 + 2*5)[1] +
                                ((npy_longlong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longlong *)data_out + 2*6)[0] =
                                ((npy_longlong *)data0 + 2*6)[0] +
                                ((npy_longlong *)data_out + 2*6)[0];
        ((npy_longlong *)data_out + 2*6)[1] =
                                ((npy_longlong *)data0 + 2*6)[1] +
                                ((npy_longlong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longlong *)data_out + 2*7)[0] =
                                ((npy_longlong *)data0 + 2*7)[0] +
                                ((npy_longlong *)data_out + 2*7)[0];
        ((npy_longlong *)data_out + 2*7)[1] =
                                ((npy_longlong *)data0 + 2*7)[1] +
                                ((npy_longlong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
longlong_sum_of_products_muladd(npy_longlong *data, npy_longlong *data_out, npy_longlong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s64;
    const npyv_s64 v_scalar = npyv_setall_s64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s64 b0 = npyv_loada_s64(data + vstep * 0);
            npyv_s64 c0 = npyv_loada_s64(data_out + vstep * 0);
            
#line 312
            npyv_s64 b1 = npyv_loada_s64(data + vstep * 1);
            npyv_s64 c1 = npyv_loada_s64(data_out + vstep * 1);
            
#line 312
            npyv_s64 b2 = npyv_loada_s64(data + vstep * 2);
            npyv_s64 c2 = npyv_loada_s64(data_out + vstep * 2);
            
#line 312
            npyv_s64 b3 = npyv_loada_s64(data + vstep * 3);
            npyv_s64 c3 = npyv_loada_s64(data_out + vstep * 3);
            
            #line 318
            npyv_s64 abc0 = npyv_muladd_s64(v_scalar, b0, c0);
            
#line 318
            npyv_s64 abc1 = npyv_muladd_s64(v_scalar, b1, c1);
            
#line 318
            npyv_s64 abc2 = npyv_muladd_s64(v_scalar, b2, c2);
            
#line 318
            npyv_s64 abc3 = npyv_muladd_s64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s64 b0 = npyv_load_s64(data + vstep * 0);
            npyv_s64 c0 = npyv_load_s64(data_out + vstep * 0);
            
#line 312
            npyv_s64 b1 = npyv_load_s64(data + vstep * 1);
            npyv_s64 c1 = npyv_load_s64(data_out + vstep * 1);
            
#line 312
            npyv_s64 b2 = npyv_load_s64(data + vstep * 2);
            npyv_s64 c2 = npyv_load_s64(data_out + vstep * 2);
            
#line 312
            npyv_s64 b3 = npyv_load_s64(data + vstep * 3);
            npyv_s64 c3 = npyv_load_s64(data_out + vstep * 3);
            
            #line 318
            npyv_s64 abc0 = npyv_muladd_s64(v_scalar, b0, c0);
            
#line 318
            npyv_s64 abc1 = npyv_muladd_s64(v_scalar, b1, c1);
            
#line 318
            npyv_s64 abc2 = npyv_muladd_s64(v_scalar, b2, c2);
            
#line 318
            npyv_s64 abc3 = npyv_muladd_s64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data, count);
        npyv_s64 b = npyv_load_tillz_s64(data_out, count);
        npyv_store_till_s64(data_out, count, npyv_muladd_s64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longlong b0 = (data[0]);
        const npy_longlong c0 = (data_out[0]);
        
#line 340
        const npy_longlong b1 = (data[1]);
        const npy_longlong c1 = (data_out[1]);
        
#line 340
        const npy_longlong b2 = (data[2]);
        const npy_longlong c2 = (data_out[2]);
        
#line 340
        const npy_longlong b3 = (data[3]);
        const npy_longlong c3 = (data_out[3]);
        
        #line 346
        const npy_longlong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longlong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longlong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longlong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longlong b = (*data);
        const npy_longlong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_longlong
}

static void
longlong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_longlong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s64 a0 = npyv_loada_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_loada_s64(data1 + vstep * 0);
            npyv_s64 c0 = npyv_loada_s64(data_out + vstep * 0);
            
#line 390
            npyv_s64 a1 = npyv_loada_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_loada_s64(data1 + vstep * 1);
            npyv_s64 c1 = npyv_loada_s64(data_out + vstep * 1);
            
#line 390
            npyv_s64 a2 = npyv_loada_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_loada_s64(data1 + vstep * 2);
            npyv_s64 c2 = npyv_loada_s64(data_out + vstep * 2);
            
#line 390
            npyv_s64 a3 = npyv_loada_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_loada_s64(data1 + vstep * 3);
            npyv_s64 c3 = npyv_loada_s64(data_out + vstep * 3);
            
            #line 397
            npyv_s64 abc0 = npyv_muladd_s64(a0, b0, c0);
            
#line 397
            npyv_s64 abc1 = npyv_muladd_s64(a1, b1, c1);
            
#line 397
            npyv_s64 abc2 = npyv_muladd_s64(a2, b2, c2);
            
#line 397
            npyv_s64 abc3 = npyv_muladd_s64(a3, b3, c3);
            
            #line 402
            npyv_storea_s64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s64 a0 = npyv_load_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_load_s64(data1 + vstep * 0);
            npyv_s64 c0 = npyv_load_s64(data_out + vstep * 0);
            
#line 390
            npyv_s64 a1 = npyv_load_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_load_s64(data1 + vstep * 1);
            npyv_s64 c1 = npyv_load_s64(data_out + vstep * 1);
            
#line 390
            npyv_s64 a2 = npyv_load_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_load_s64(data1 + vstep * 2);
            npyv_s64 c2 = npyv_load_s64(data_out + vstep * 2);
            
#line 390
            npyv_s64 a3 = npyv_load_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_load_s64(data1 + vstep * 3);
            npyv_s64 c3 = npyv_load_s64(data_out + vstep * 3);
            
            #line 397
            npyv_s64 abc0 = npyv_muladd_s64(a0, b0, c0);
            
#line 397
            npyv_s64 abc1 = npyv_muladd_s64(a1, b1, c1);
            
#line 397
            npyv_s64 abc2 = npyv_muladd_s64(a2, b2, c2);
            
#line 397
            npyv_s64 abc3 = npyv_muladd_s64(a3, b3, c3);
            
            #line 402
            npyv_store_s64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data0, count);
        npyv_s64 b = npyv_load_tillz_s64(data1, count);
        npyv_s64 c = npyv_load_tillz_s64(data_out, count);
        npyv_store_till_s64(data_out, count, npyv_muladd_s64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longlong a0 = (data0[0]);
        const npy_longlong b0 = (data1[0]);
        const npy_longlong c0 = (data_out[0]);
        
#line 420
        const npy_longlong a1 = (data0[1]);
        const npy_longlong b1 = (data1[1]);
        const npy_longlong c1 = (data_out[1]);
        
#line 420
        const npy_longlong a2 = (data0[2]);
        const npy_longlong b2 = (data1[2]);
        const npy_longlong c2 = (data_out[2]);
        
#line 420
        const npy_longlong a3 = (data0[3]);
        const npy_longlong b3 = (data1[3]);
        const npy_longlong c3 = (data_out[3]);
        
        #line 427
        const npy_longlong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longlong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longlong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longlong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longlong a = (*data0);
        const npy_longlong b = (*data1);
        const npy_longlong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_longlong

}

/* Some extra specializations for the two operand case */
static void
longlong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong value0 = (*(npy_longlong *)dataptr[0]);
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    longlong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
longlong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong value1 = (*(npy_longlong *)dataptr[1]);
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    longlong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong accum = 0;

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s64;
    npyv_s64 v_accum = npyv_zero_s64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s64 a0 = npyv_loada_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_loada_s64(data1 + vstep * 0);
            
#line 501
            npyv_s64 a1 = npyv_loada_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_loada_s64(data1 + vstep * 1);
            
#line 501
            npyv_s64 a2 = npyv_loada_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_loada_s64(data1 + vstep * 2);
            
#line 501
            npyv_s64 a3 = npyv_loada_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_loada_s64(data1 + vstep * 3);
            
            npyv_s64 ab3 = npyv_muladd_s64(a3, b3, v_accum);
            npyv_s64 ab2 = npyv_muladd_s64(a2, b2, ab3);
            npyv_s64 ab1 = npyv_muladd_s64(a1, b1, ab2);
                   v_accum = npyv_muladd_s64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s64 a0 = npyv_load_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_load_s64(data1 + vstep * 0);
            
#line 501
            npyv_s64 a1 = npyv_load_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_load_s64(data1 + vstep * 1);
            
#line 501
            npyv_s64 a2 = npyv_load_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_load_s64(data1 + vstep * 2);
            
#line 501
            npyv_s64 a3 = npyv_load_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_load_s64(data1 + vstep * 3);
            
            npyv_s64 ab3 = npyv_muladd_s64(a3, b3, v_accum);
            npyv_s64 ab2 = npyv_muladd_s64(a2, b2, ab3);
            npyv_s64 ab1 = npyv_muladd_s64(a1, b1, ab2);
                   v_accum = npyv_muladd_s64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data0, count);
        npyv_s64 b = npyv_load_tillz_s64(data1, count);
        v_accum = npyv_muladd_s64(a, b, v_accum);
    }
    accum = npyv_sum_s64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longlong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longlong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longlong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longlong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longlong a = (*data0);
        const npy_longlong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_longlong
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong value0 = (*(npy_longlong *)dataptr[0]);
    npy_longlong accum = longlong_sum_of_arr(data1, count);
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong value1 = (*(npy_longlong *)dataptr[1]);
    npy_longlong accum = longlong_sum_of_arr(data0, count);
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
longlong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data2 = (npy_longlong *)dataptr[2];
    npy_longlong *data_out = (npy_longlong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
longlong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        *(npy_longlong *)dataptr[nop] = (temp +
                                           (*(npy_longlong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_longlong);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_longlong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_longlong *data = (npy_longlong *)dataptr[0];
    npy_longlong accum = longlong_sum_of_arr(data, count);
    *((npy_longlong *)dataptr[1]) = (accum + (*((npy_longlong *)dataptr[1])));
#else
    npy_longlong accum_re = 0, accum_im = 0;
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longlong re01 = data0[0] + data0[2];
        const npy_longlong re23 = data0[4] + data0[6];
        const npy_longlong im13 = data0[1] + data0[3];
        const npy_longlong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longlong *)dataptr[1])[0] += accum_re;
    ((npy_longlong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
longlong_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_longlong accum_re = 0, accum_im = 0;
#else
    npy_longlong accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_longlong *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_longlong *)data0) *
                 (*(npy_longlong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_longlong *)data0) *
                 (*(npy_longlong *)data1) *
                 (*(npy_longlong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_longlong *)data0)[0];
        accum_im += ((npy_longlong *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_longlong *)dataptr[3])[0] += accum_re;
    ((npy_longlong *)dataptr[3])[1] += accum_im;
#  else
    ((npy_longlong *)dataptr[nop])[0] += accum_re;
    ((npy_longlong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_longlong *)dataptr[3]) = (accum +
                                    (*((npy_longlong *)dataptr[3])));
#  else
    *((npy_longlong *)dataptr[nop]) = (accum +
                                    (*((npy_longlong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
longlong_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) *
                                         (*(npy_longlong *)data1) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_longlong *)data_out = ((*(npy_longlong *)data0) *
                                         (*(npy_longlong *)data1) *
                                         (*(npy_longlong *)data2) +
                                         (*(npy_longlong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        *(npy_longlong *)dataptr[nop] = (temp +
                                           (*(npy_longlong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_longlong *)data_out)[0] = ((npy_longlong *)data0)[0] +
                                         ((npy_longlong *)data_out)[0];
        ((npy_longlong *)data_out)[1] = ((npy_longlong *)data0)[1] +
                                         ((npy_longlong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
longlong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data_out = (npy_longlong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longlong *)data_out + 2*6)[0] =
                                    ((npy_longlong *)data0 + 2*6)[0] +
                                    ((npy_longlong *)data_out + 2*6)[0];
            ((npy_longlong *)data_out + 2*6)[1] =
                                    ((npy_longlong *)data0 + 2*6)[1] +
                                    ((npy_longlong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longlong *)data_out + 2*5)[0] =
                                    ((npy_longlong *)data0 + 2*5)[0] +
                                    ((npy_longlong *)data_out + 2*5)[0];
            ((npy_longlong *)data_out + 2*5)[1] =
                                    ((npy_longlong *)data0 + 2*5)[1] +
                                    ((npy_longlong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longlong *)data_out + 2*4)[0] =
                                    ((npy_longlong *)data0 + 2*4)[0] +
                                    ((npy_longlong *)data_out + 2*4)[0];
            ((npy_longlong *)data_out + 2*4)[1] =
                                    ((npy_longlong *)data0 + 2*4)[1] +
                                    ((npy_longlong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longlong *)data_out + 2*3)[0] =
                                    ((npy_longlong *)data0 + 2*3)[0] +
                                    ((npy_longlong *)data_out + 2*3)[0];
            ((npy_longlong *)data_out + 2*3)[1] =
                                    ((npy_longlong *)data0 + 2*3)[1] +
                                    ((npy_longlong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longlong *)data_out + 2*2)[0] =
                                    ((npy_longlong *)data0 + 2*2)[0] +
                                    ((npy_longlong *)data_out + 2*2)[0];
            ((npy_longlong *)data_out + 2*2)[1] =
                                    ((npy_longlong *)data0 + 2*2)[1] +
                                    ((npy_longlong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longlong *)data_out + 2*1)[0] =
                                    ((npy_longlong *)data0 + 2*1)[0] +
                                    ((npy_longlong *)data_out + 2*1)[0];
            ((npy_longlong *)data_out + 2*1)[1] =
                                    ((npy_longlong *)data0 + 2*1)[1] +
                                    ((npy_longlong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longlong *)data_out + 2*0)[0] =
                                    ((npy_longlong *)data0 + 2*0)[0] +
                                    ((npy_longlong *)data_out + 2*0)[0];
            ((npy_longlong *)data_out + 2*0)[1] =
                                    ((npy_longlong *)data0 + 2*0)[1] +
                                    ((npy_longlong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longlong *)data_out + 2*0)[0] =
                                ((npy_longlong *)data0 + 2*0)[0] +
                                ((npy_longlong *)data_out + 2*0)[0];
        ((npy_longlong *)data_out + 2*0)[1] =
                                ((npy_longlong *)data0 + 2*0)[1] +
                                ((npy_longlong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longlong *)data_out + 2*1)[0] =
                                ((npy_longlong *)data0 + 2*1)[0] +
                                ((npy_longlong *)data_out + 2*1)[0];
        ((npy_longlong *)data_out + 2*1)[1] =
                                ((npy_longlong *)data0 + 2*1)[1] +
                                ((npy_longlong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longlong *)data_out + 2*2)[0] =
                                ((npy_longlong *)data0 + 2*2)[0] +
                                ((npy_longlong *)data_out + 2*2)[0];
        ((npy_longlong *)data_out + 2*2)[1] =
                                ((npy_longlong *)data0 + 2*2)[1] +
                                ((npy_longlong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longlong *)data_out + 2*3)[0] =
                                ((npy_longlong *)data0 + 2*3)[0] +
                                ((npy_longlong *)data_out + 2*3)[0];
        ((npy_longlong *)data_out + 2*3)[1] =
                                ((npy_longlong *)data0 + 2*3)[1] +
                                ((npy_longlong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longlong *)data_out + 2*4)[0] =
                                ((npy_longlong *)data0 + 2*4)[0] +
                                ((npy_longlong *)data_out + 2*4)[0];
        ((npy_longlong *)data_out + 2*4)[1] =
                                ((npy_longlong *)data0 + 2*4)[1] +
                                ((npy_longlong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longlong *)data_out + 2*5)[0] =
                                ((npy_longlong *)data0 + 2*5)[0] +
                                ((npy_longlong *)data_out + 2*5)[0];
        ((npy_longlong *)data_out + 2*5)[1] =
                                ((npy_longlong *)data0 + 2*5)[1] +
                                ((npy_longlong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longlong *)data_out + 2*6)[0] =
                                ((npy_longlong *)data0 + 2*6)[0] +
                                ((npy_longlong *)data_out + 2*6)[0];
        ((npy_longlong *)data_out + 2*6)[1] =
                                ((npy_longlong *)data0 + 2*6)[1] +
                                ((npy_longlong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longlong *)data_out + 2*7)[0] =
                                ((npy_longlong *)data0 + 2*7)[0] +
                                ((npy_longlong *)data_out + 2*7)[0];
        ((npy_longlong *)data_out + 2*7)[1] =
                                ((npy_longlong *)data0 + 2*7)[1] +
                                ((npy_longlong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
longlong_sum_of_products_muladd(npy_longlong *data, npy_longlong *data_out, npy_longlong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s64;
    const npyv_s64 v_scalar = npyv_setall_s64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s64 b0 = npyv_loada_s64(data + vstep * 0);
            npyv_s64 c0 = npyv_loada_s64(data_out + vstep * 0);
            
#line 312
            npyv_s64 b1 = npyv_loada_s64(data + vstep * 1);
            npyv_s64 c1 = npyv_loada_s64(data_out + vstep * 1);
            
#line 312
            npyv_s64 b2 = npyv_loada_s64(data + vstep * 2);
            npyv_s64 c2 = npyv_loada_s64(data_out + vstep * 2);
            
#line 312
            npyv_s64 b3 = npyv_loada_s64(data + vstep * 3);
            npyv_s64 c3 = npyv_loada_s64(data_out + vstep * 3);
            
            #line 318
            npyv_s64 abc0 = npyv_muladd_s64(v_scalar, b0, c0);
            
#line 318
            npyv_s64 abc1 = npyv_muladd_s64(v_scalar, b1, c1);
            
#line 318
            npyv_s64 abc2 = npyv_muladd_s64(v_scalar, b2, c2);
            
#line 318
            npyv_s64 abc3 = npyv_muladd_s64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_s64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_s64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_s64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_s64 b0 = npyv_load_s64(data + vstep * 0);
            npyv_s64 c0 = npyv_load_s64(data_out + vstep * 0);
            
#line 312
            npyv_s64 b1 = npyv_load_s64(data + vstep * 1);
            npyv_s64 c1 = npyv_load_s64(data_out + vstep * 1);
            
#line 312
            npyv_s64 b2 = npyv_load_s64(data + vstep * 2);
            npyv_s64 c2 = npyv_load_s64(data_out + vstep * 2);
            
#line 312
            npyv_s64 b3 = npyv_load_s64(data + vstep * 3);
            npyv_s64 c3 = npyv_load_s64(data_out + vstep * 3);
            
            #line 318
            npyv_s64 abc0 = npyv_muladd_s64(v_scalar, b0, c0);
            
#line 318
            npyv_s64 abc1 = npyv_muladd_s64(v_scalar, b1, c1);
            
#line 318
            npyv_s64 abc2 = npyv_muladd_s64(v_scalar, b2, c2);
            
#line 318
            npyv_s64 abc3 = npyv_muladd_s64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_s64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_s64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_s64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data, count);
        npyv_s64 b = npyv_load_tillz_s64(data_out, count);
        npyv_store_till_s64(data_out, count, npyv_muladd_s64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longlong b0 = (data[0]);
        const npy_longlong c0 = (data_out[0]);
        
#line 340
        const npy_longlong b1 = (data[1]);
        const npy_longlong c1 = (data_out[1]);
        
#line 340
        const npy_longlong b2 = (data[2]);
        const npy_longlong c2 = (data_out[2]);
        
#line 340
        const npy_longlong b3 = (data[3]);
        const npy_longlong c3 = (data_out[3]);
        
        #line 346
        const npy_longlong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longlong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longlong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longlong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longlong b = (*data);
        const npy_longlong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_longlong
}

static void
longlong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_longlong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_s64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s64 a0 = npyv_loada_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_loada_s64(data1 + vstep * 0);
            npyv_s64 c0 = npyv_loada_s64(data_out + vstep * 0);
            
#line 390
            npyv_s64 a1 = npyv_loada_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_loada_s64(data1 + vstep * 1);
            npyv_s64 c1 = npyv_loada_s64(data_out + vstep * 1);
            
#line 390
            npyv_s64 a2 = npyv_loada_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_loada_s64(data1 + vstep * 2);
            npyv_s64 c2 = npyv_loada_s64(data_out + vstep * 2);
            
#line 390
            npyv_s64 a3 = npyv_loada_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_loada_s64(data1 + vstep * 3);
            npyv_s64 c3 = npyv_loada_s64(data_out + vstep * 3);
            
            #line 397
            npyv_s64 abc0 = npyv_muladd_s64(a0, b0, c0);
            
#line 397
            npyv_s64 abc1 = npyv_muladd_s64(a1, b1, c1);
            
#line 397
            npyv_s64 abc2 = npyv_muladd_s64(a2, b2, c2);
            
#line 397
            npyv_s64 abc3 = npyv_muladd_s64(a3, b3, c3);
            
            #line 402
            npyv_storea_s64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_s64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_s64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_s64 a0 = npyv_load_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_load_s64(data1 + vstep * 0);
            npyv_s64 c0 = npyv_load_s64(data_out + vstep * 0);
            
#line 390
            npyv_s64 a1 = npyv_load_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_load_s64(data1 + vstep * 1);
            npyv_s64 c1 = npyv_load_s64(data_out + vstep * 1);
            
#line 390
            npyv_s64 a2 = npyv_load_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_load_s64(data1 + vstep * 2);
            npyv_s64 c2 = npyv_load_s64(data_out + vstep * 2);
            
#line 390
            npyv_s64 a3 = npyv_load_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_load_s64(data1 + vstep * 3);
            npyv_s64 c3 = npyv_load_s64(data_out + vstep * 3);
            
            #line 397
            npyv_s64 abc0 = npyv_muladd_s64(a0, b0, c0);
            
#line 397
            npyv_s64 abc1 = npyv_muladd_s64(a1, b1, c1);
            
#line 397
            npyv_s64 abc2 = npyv_muladd_s64(a2, b2, c2);
            
#line 397
            npyv_s64 abc3 = npyv_muladd_s64(a3, b3, c3);
            
            #line 402
            npyv_store_s64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_s64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_s64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_s64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data0, count);
        npyv_s64 b = npyv_load_tillz_s64(data1, count);
        npyv_s64 c = npyv_load_tillz_s64(data_out, count);
        npyv_store_till_s64(data_out, count, npyv_muladd_s64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longlong a0 = (data0[0]);
        const npy_longlong b0 = (data1[0]);
        const npy_longlong c0 = (data_out[0]);
        
#line 420
        const npy_longlong a1 = (data0[1]);
        const npy_longlong b1 = (data1[1]);
        const npy_longlong c1 = (data_out[1]);
        
#line 420
        const npy_longlong a2 = (data0[2]);
        const npy_longlong b2 = (data1[2]);
        const npy_longlong c2 = (data_out[2]);
        
#line 420
        const npy_longlong a3 = (data0[3]);
        const npy_longlong b3 = (data1[3]);
        const npy_longlong c3 = (data_out[3]);
        
        #line 427
        const npy_longlong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longlong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longlong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longlong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longlong a = (*data0);
        const npy_longlong b = (*data1);
        const npy_longlong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_longlong

}

/* Some extra specializations for the two operand case */
static void
longlong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong value0 = (*(npy_longlong *)dataptr[0]);
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    longlong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
longlong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong value1 = (*(npy_longlong *)dataptr[1]);
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data_out = (npy_longlong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    longlong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong accum = 0;

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_longlong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_s64;
    npyv_s64 v_accum = npyv_zero_s64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s64 a0 = npyv_loada_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_loada_s64(data1 + vstep * 0);
            
#line 501
            npyv_s64 a1 = npyv_loada_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_loada_s64(data1 + vstep * 1);
            
#line 501
            npyv_s64 a2 = npyv_loada_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_loada_s64(data1 + vstep * 2);
            
#line 501
            npyv_s64 a3 = npyv_loada_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_loada_s64(data1 + vstep * 3);
            
            npyv_s64 ab3 = npyv_muladd_s64(a3, b3, v_accum);
            npyv_s64 ab2 = npyv_muladd_s64(a2, b2, ab3);
            npyv_s64 ab1 = npyv_muladd_s64(a1, b1, ab2);
                   v_accum = npyv_muladd_s64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_s64 a0 = npyv_load_s64(data0 + vstep * 0);
            npyv_s64 b0 = npyv_load_s64(data1 + vstep * 0);
            
#line 501
            npyv_s64 a1 = npyv_load_s64(data0 + vstep * 1);
            npyv_s64 b1 = npyv_load_s64(data1 + vstep * 1);
            
#line 501
            npyv_s64 a2 = npyv_load_s64(data0 + vstep * 2);
            npyv_s64 b2 = npyv_load_s64(data1 + vstep * 2);
            
#line 501
            npyv_s64 a3 = npyv_load_s64(data0 + vstep * 3);
            npyv_s64 b3 = npyv_load_s64(data1 + vstep * 3);
            
            npyv_s64 ab3 = npyv_muladd_s64(a3, b3, v_accum);
            npyv_s64 ab2 = npyv_muladd_s64(a2, b2, ab3);
            npyv_s64 ab1 = npyv_muladd_s64(a1, b1, ab2);
                   v_accum = npyv_muladd_s64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_s64 a = npyv_load_tillz_s64(data0, count);
        npyv_s64 b = npyv_load_tillz_s64(data1, count);
        v_accum = npyv_muladd_s64(a, b, v_accum);
    }
    accum = npyv_sum_s64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longlong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longlong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longlong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longlong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longlong a = (*data0);
        const npy_longlong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_longlong
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong value0 = (*(npy_longlong *)dataptr[0]);
    npy_longlong accum = longlong_sum_of_arr(data1, count);
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong value1 = (*(npy_longlong *)dataptr[1]);
    npy_longlong accum = longlong_sum_of_arr(data0, count);
    *(npy_longlong *)dataptr[2] = ((*(npy_longlong *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
longlong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
    npy_longlong *data1 = (npy_longlong *)dataptr[1];
    npy_longlong *data2 = (npy_longlong *)dataptr[2];
    npy_longlong *data_out = (npy_longlong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
longlong_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        *(npy_longlong *)dataptr[nop] = (temp +
                                           (*(npy_longlong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_longlong);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longlong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longlong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_longlong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
longlong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_longlong *data = (npy_longlong *)dataptr[0];
    npy_longlong accum = longlong_sum_of_arr(data, count);
    *((npy_longlong *)dataptr[1]) = (accum + (*((npy_longlong *)dataptr[1])));
#else
    npy_longlong accum_re = 0, accum_im = 0;
    npy_longlong *data0 = (npy_longlong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longlong re01 = data0[0] + data0[2];
        const npy_longlong re23 = data0[4] + data0[6];
        const npy_longlong im13 = data0[1] + data0[3];
        const npy_longlong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longlong *)dataptr[1])[0] += accum_re;
    ((npy_longlong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
longlong_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_longlong accum_re = 0, accum_im = 0;
#else
    npy_longlong accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longlong_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_longlong *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_longlong *)data0) *
                 (*(npy_longlong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_longlong *)data0) *
                 (*(npy_longlong *)data1) *
                 (*(npy_longlong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longlong temp = (*(npy_longlong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longlong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_longlong *)data0)[0];
        accum_im += ((npy_longlong *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longlong re, im, tmp;
        int i;
        re = ((npy_longlong *)dataptr[0])[0];
        im = ((npy_longlong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longlong *)dataptr[i])[0] -
                  im * ((npy_longlong *)dataptr[i])[1];
            im = re * ((npy_longlong *)dataptr[i])[1] +
                 im * ((npy_longlong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_longlong *)dataptr[1000])[0] += accum_re;
    ((npy_longlong *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_longlong *)dataptr[nop])[0] += accum_re;
    ((npy_longlong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_longlong *)dataptr[1000]) = (accum +
                                    (*((npy_longlong *)dataptr[1000])));
#  else
    *((npy_longlong *)dataptr[nop]) = (accum +
                                    (*((npy_longlong *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_ubyte ubyte_sum_of_arr(npy_ubyte *data, npy_intp count)
{
    npy_ubyte accum = 0;
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_u8;
    npyv_u8 v_accum = npyv_zero_u8();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_u8 a0 = npyv_loada_u8(data + vstep * 0);
            
#line 96
            npyv_u8 a1 = npyv_loada_u8(data + vstep * 1);
            
#line 96
            npyv_u8 a2 = npyv_loada_u8(data + vstep * 2);
            
#line 96
            npyv_u8 a3 = npyv_loada_u8(data + vstep * 3);
            
            npyv_u8 a01   = npyv_add_u8(a0, a1);
            npyv_u8 a23   = npyv_add_u8(a2, a3);
            npyv_u8 a0123 = npyv_add_u8(a01, a23);
                     v_accum = npyv_add_u8(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_u8 a0 = npyv_load_u8(data + vstep * 0);
            
#line 96
            npyv_u8 a1 = npyv_load_u8(data + vstep * 1);
            
#line 96
            npyv_u8 a2 = npyv_load_u8(data + vstep * 2);
            
#line 96
            npyv_u8 a3 = npyv_load_u8(data + vstep * 3);
            
            npyv_u8 a01   = npyv_add_u8(a0, a1);
            npyv_u8 a23   = npyv_add_u8(a2, a3);
            npyv_u8 a0123 = npyv_add_u8(a01, a23);
                     v_accum = npyv_add_u8(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data, count);
        v_accum = npyv_add_u8(a, v_accum);
    }
    accum = npyv_sum_u8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_ubyte a01 = (*data) + (data[1]);
        const npy_ubyte a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_ubyte
    return accum;
}
#endif

#line 131
static void
ubyte_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) *
                                         (*(npy_ubyte *)data1) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) *
                                         (*(npy_ubyte *)data1) *
                                         (*(npy_ubyte *)data2) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        *(npy_ubyte *)dataptr[nop] = (temp +
                                           (*(npy_ubyte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_ubyte *)data_out)[0] = ((npy_ubyte *)data0)[0] +
                                         ((npy_ubyte *)data_out)[0];
        ((npy_ubyte *)data_out)[1] = ((npy_ubyte *)data0)[1] +
                                         ((npy_ubyte *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
ubyte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ubyte *)data_out + 2*6)[0] =
                                    ((npy_ubyte *)data0 + 2*6)[0] +
                                    ((npy_ubyte *)data_out + 2*6)[0];
            ((npy_ubyte *)data_out + 2*6)[1] =
                                    ((npy_ubyte *)data0 + 2*6)[1] +
                                    ((npy_ubyte *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ubyte *)data_out + 2*5)[0] =
                                    ((npy_ubyte *)data0 + 2*5)[0] +
                                    ((npy_ubyte *)data_out + 2*5)[0];
            ((npy_ubyte *)data_out + 2*5)[1] =
                                    ((npy_ubyte *)data0 + 2*5)[1] +
                                    ((npy_ubyte *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ubyte *)data_out + 2*4)[0] =
                                    ((npy_ubyte *)data0 + 2*4)[0] +
                                    ((npy_ubyte *)data_out + 2*4)[0];
            ((npy_ubyte *)data_out + 2*4)[1] =
                                    ((npy_ubyte *)data0 + 2*4)[1] +
                                    ((npy_ubyte *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ubyte *)data_out + 2*3)[0] =
                                    ((npy_ubyte *)data0 + 2*3)[0] +
                                    ((npy_ubyte *)data_out + 2*3)[0];
            ((npy_ubyte *)data_out + 2*3)[1] =
                                    ((npy_ubyte *)data0 + 2*3)[1] +
                                    ((npy_ubyte *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ubyte *)data_out + 2*2)[0] =
                                    ((npy_ubyte *)data0 + 2*2)[0] +
                                    ((npy_ubyte *)data_out + 2*2)[0];
            ((npy_ubyte *)data_out + 2*2)[1] =
                                    ((npy_ubyte *)data0 + 2*2)[1] +
                                    ((npy_ubyte *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ubyte *)data_out + 2*1)[0] =
                                    ((npy_ubyte *)data0 + 2*1)[0] +
                                    ((npy_ubyte *)data_out + 2*1)[0];
            ((npy_ubyte *)data_out + 2*1)[1] =
                                    ((npy_ubyte *)data0 + 2*1)[1] +
                                    ((npy_ubyte *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ubyte *)data_out + 2*0)[0] =
                                    ((npy_ubyte *)data0 + 2*0)[0] +
                                    ((npy_ubyte *)data_out + 2*0)[0];
            ((npy_ubyte *)data_out + 2*0)[1] =
                                    ((npy_ubyte *)data0 + 2*0)[1] +
                                    ((npy_ubyte *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*0)[0] =
                                ((npy_ubyte *)data0 + 2*0)[0] +
                                ((npy_ubyte *)data_out + 2*0)[0];
        ((npy_ubyte *)data_out + 2*0)[1] =
                                ((npy_ubyte *)data0 + 2*0)[1] +
                                ((npy_ubyte *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*1)[0] =
                                ((npy_ubyte *)data0 + 2*1)[0] +
                                ((npy_ubyte *)data_out + 2*1)[0];
        ((npy_ubyte *)data_out + 2*1)[1] =
                                ((npy_ubyte *)data0 + 2*1)[1] +
                                ((npy_ubyte *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*2)[0] =
                                ((npy_ubyte *)data0 + 2*2)[0] +
                                ((npy_ubyte *)data_out + 2*2)[0];
        ((npy_ubyte *)data_out + 2*2)[1] =
                                ((npy_ubyte *)data0 + 2*2)[1] +
                                ((npy_ubyte *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*3)[0] =
                                ((npy_ubyte *)data0 + 2*3)[0] +
                                ((npy_ubyte *)data_out + 2*3)[0];
        ((npy_ubyte *)data_out + 2*3)[1] =
                                ((npy_ubyte *)data0 + 2*3)[1] +
                                ((npy_ubyte *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*4)[0] =
                                ((npy_ubyte *)data0 + 2*4)[0] +
                                ((npy_ubyte *)data_out + 2*4)[0];
        ((npy_ubyte *)data_out + 2*4)[1] =
                                ((npy_ubyte *)data0 + 2*4)[1] +
                                ((npy_ubyte *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*5)[0] =
                                ((npy_ubyte *)data0 + 2*5)[0] +
                                ((npy_ubyte *)data_out + 2*5)[0];
        ((npy_ubyte *)data_out + 2*5)[1] =
                                ((npy_ubyte *)data0 + 2*5)[1] +
                                ((npy_ubyte *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*6)[0] =
                                ((npy_ubyte *)data0 + 2*6)[0] +
                                ((npy_ubyte *)data_out + 2*6)[0];
        ((npy_ubyte *)data_out + 2*6)[1] =
                                ((npy_ubyte *)data0 + 2*6)[1] +
                                ((npy_ubyte *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*7)[0] =
                                ((npy_ubyte *)data0 + 2*7)[0] +
                                ((npy_ubyte *)data_out + 2*7)[0];
        ((npy_ubyte *)data_out + 2*7)[1] =
                                ((npy_ubyte *)data0 + 2*7)[1] +
                                ((npy_ubyte *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ubyte_sum_of_products_muladd(npy_ubyte *data, npy_ubyte *data_out, npy_ubyte scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u8;
    const npyv_u8 v_scalar = npyv_setall_u8(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u8 b0 = npyv_loada_u8(data + vstep * 0);
            npyv_u8 c0 = npyv_loada_u8(data_out + vstep * 0);
            
#line 312
            npyv_u8 b1 = npyv_loada_u8(data + vstep * 1);
            npyv_u8 c1 = npyv_loada_u8(data_out + vstep * 1);
            
#line 312
            npyv_u8 b2 = npyv_loada_u8(data + vstep * 2);
            npyv_u8 c2 = npyv_loada_u8(data_out + vstep * 2);
            
#line 312
            npyv_u8 b3 = npyv_loada_u8(data + vstep * 3);
            npyv_u8 c3 = npyv_loada_u8(data_out + vstep * 3);
            
            #line 318
            npyv_u8 abc0 = npyv_muladd_u8(v_scalar, b0, c0);
            
#line 318
            npyv_u8 abc1 = npyv_muladd_u8(v_scalar, b1, c1);
            
#line 318
            npyv_u8 abc2 = npyv_muladd_u8(v_scalar, b2, c2);
            
#line 318
            npyv_u8 abc3 = npyv_muladd_u8(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u8 b0 = npyv_load_u8(data + vstep * 0);
            npyv_u8 c0 = npyv_load_u8(data_out + vstep * 0);
            
#line 312
            npyv_u8 b1 = npyv_load_u8(data + vstep * 1);
            npyv_u8 c1 = npyv_load_u8(data_out + vstep * 1);
            
#line 312
            npyv_u8 b2 = npyv_load_u8(data + vstep * 2);
            npyv_u8 c2 = npyv_load_u8(data_out + vstep * 2);
            
#line 312
            npyv_u8 b3 = npyv_load_u8(data + vstep * 3);
            npyv_u8 c3 = npyv_load_u8(data_out + vstep * 3);
            
            #line 318
            npyv_u8 abc0 = npyv_muladd_u8(v_scalar, b0, c0);
            
#line 318
            npyv_u8 abc1 = npyv_muladd_u8(v_scalar, b1, c1);
            
#line 318
            npyv_u8 abc2 = npyv_muladd_u8(v_scalar, b2, c2);
            
#line 318
            npyv_u8 abc3 = npyv_muladd_u8(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data, count);
        npyv_u8 b = npyv_load_tillz_u8(data_out, count);
        npyv_store_till_u8(data_out, count, npyv_muladd_u8(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ubyte b0 = (data[0]);
        const npy_ubyte c0 = (data_out[0]);
        
#line 340
        const npy_ubyte b1 = (data[1]);
        const npy_ubyte c1 = (data_out[1]);
        
#line 340
        const npy_ubyte b2 = (data[2]);
        const npy_ubyte c2 = (data_out[2]);
        
#line 340
        const npy_ubyte b3 = (data[3]);
        const npy_ubyte c3 = (data_out[3]);
        
        #line 346
        const npy_ubyte abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ubyte abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ubyte abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ubyte abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ubyte b = (*data);
        const npy_ubyte c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ubyte
}

static void
ubyte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ubyte
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u8;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u8 a0 = npyv_loada_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_loada_u8(data1 + vstep * 0);
            npyv_u8 c0 = npyv_loada_u8(data_out + vstep * 0);
            
#line 390
            npyv_u8 a1 = npyv_loada_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_loada_u8(data1 + vstep * 1);
            npyv_u8 c1 = npyv_loada_u8(data_out + vstep * 1);
            
#line 390
            npyv_u8 a2 = npyv_loada_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_loada_u8(data1 + vstep * 2);
            npyv_u8 c2 = npyv_loada_u8(data_out + vstep * 2);
            
#line 390
            npyv_u8 a3 = npyv_loada_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_loada_u8(data1 + vstep * 3);
            npyv_u8 c3 = npyv_loada_u8(data_out + vstep * 3);
            
            #line 397
            npyv_u8 abc0 = npyv_muladd_u8(a0, b0, c0);
            
#line 397
            npyv_u8 abc1 = npyv_muladd_u8(a1, b1, c1);
            
#line 397
            npyv_u8 abc2 = npyv_muladd_u8(a2, b2, c2);
            
#line 397
            npyv_u8 abc3 = npyv_muladd_u8(a3, b3, c3);
            
            #line 402
            npyv_storea_u8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u8 a0 = npyv_load_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_load_u8(data1 + vstep * 0);
            npyv_u8 c0 = npyv_load_u8(data_out + vstep * 0);
            
#line 390
            npyv_u8 a1 = npyv_load_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_load_u8(data1 + vstep * 1);
            npyv_u8 c1 = npyv_load_u8(data_out + vstep * 1);
            
#line 390
            npyv_u8 a2 = npyv_load_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_load_u8(data1 + vstep * 2);
            npyv_u8 c2 = npyv_load_u8(data_out + vstep * 2);
            
#line 390
            npyv_u8 a3 = npyv_load_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_load_u8(data1 + vstep * 3);
            npyv_u8 c3 = npyv_load_u8(data_out + vstep * 3);
            
            #line 397
            npyv_u8 abc0 = npyv_muladd_u8(a0, b0, c0);
            
#line 397
            npyv_u8 abc1 = npyv_muladd_u8(a1, b1, c1);
            
#line 397
            npyv_u8 abc2 = npyv_muladd_u8(a2, b2, c2);
            
#line 397
            npyv_u8 abc3 = npyv_muladd_u8(a3, b3, c3);
            
            #line 402
            npyv_store_u8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data0, count);
        npyv_u8 b = npyv_load_tillz_u8(data1, count);
        npyv_u8 c = npyv_load_tillz_u8(data_out, count);
        npyv_store_till_u8(data_out, count, npyv_muladd_u8(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ubyte a0 = (data0[0]);
        const npy_ubyte b0 = (data1[0]);
        const npy_ubyte c0 = (data_out[0]);
        
#line 420
        const npy_ubyte a1 = (data0[1]);
        const npy_ubyte b1 = (data1[1]);
        const npy_ubyte c1 = (data_out[1]);
        
#line 420
        const npy_ubyte a2 = (data0[2]);
        const npy_ubyte b2 = (data1[2]);
        const npy_ubyte c2 = (data_out[2]);
        
#line 420
        const npy_ubyte a3 = (data0[3]);
        const npy_ubyte b3 = (data1[3]);
        const npy_ubyte c3 = (data_out[3]);
        
        #line 427
        const npy_ubyte abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ubyte abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ubyte abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ubyte abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ubyte a = (*data0);
        const npy_ubyte b = (*data1);
        const npy_ubyte c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ubyte

}

/* Some extra specializations for the two operand case */
static void
ubyte_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte value0 = (*(npy_ubyte *)dataptr[0]);
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ubyte_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ubyte_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte value1 = (*(npy_ubyte *)dataptr[1]);
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ubyte_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte accum = 0;

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u8;
    npyv_u8 v_accum = npyv_zero_u8();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u8 a0 = npyv_loada_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_loada_u8(data1 + vstep * 0);
            
#line 501
            npyv_u8 a1 = npyv_loada_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_loada_u8(data1 + vstep * 1);
            
#line 501
            npyv_u8 a2 = npyv_loada_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_loada_u8(data1 + vstep * 2);
            
#line 501
            npyv_u8 a3 = npyv_loada_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_loada_u8(data1 + vstep * 3);
            
            npyv_u8 ab3 = npyv_muladd_u8(a3, b3, v_accum);
            npyv_u8 ab2 = npyv_muladd_u8(a2, b2, ab3);
            npyv_u8 ab1 = npyv_muladd_u8(a1, b1, ab2);
                   v_accum = npyv_muladd_u8(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u8 a0 = npyv_load_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_load_u8(data1 + vstep * 0);
            
#line 501
            npyv_u8 a1 = npyv_load_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_load_u8(data1 + vstep * 1);
            
#line 501
            npyv_u8 a2 = npyv_load_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_load_u8(data1 + vstep * 2);
            
#line 501
            npyv_u8 a3 = npyv_load_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_load_u8(data1 + vstep * 3);
            
            npyv_u8 ab3 = npyv_muladd_u8(a3, b3, v_accum);
            npyv_u8 ab2 = npyv_muladd_u8(a2, b2, ab3);
            npyv_u8 ab1 = npyv_muladd_u8(a1, b1, ab2);
                   v_accum = npyv_muladd_u8(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data0, count);
        npyv_u8 b = npyv_load_tillz_u8(data1, count);
        v_accum = npyv_muladd_u8(a, b, v_accum);
    }
    accum = npyv_sum_u8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ubyte ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ubyte ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ubyte ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ubyte ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ubyte a = (*data0);
        const npy_ubyte b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ubyte
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte value0 = (*(npy_ubyte *)dataptr[0]);
    npy_ubyte accum = ubyte_sum_of_arr(data1, count);
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte value1 = (*(npy_ubyte *)dataptr[1]);
    npy_ubyte accum = ubyte_sum_of_arr(data0, count);
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
ubyte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data2 = (npy_ubyte *)dataptr[2];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
ubyte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        *(npy_ubyte *)dataptr[nop] = (temp +
                                           (*(npy_ubyte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ubyte);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ubyte);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ubyte *data = (npy_ubyte *)dataptr[0];
    npy_ubyte accum = ubyte_sum_of_arr(data, count);
    *((npy_ubyte *)dataptr[1]) = (accum + (*((npy_ubyte *)dataptr[1])));
#else
    npy_ubyte accum_re = 0, accum_im = 0;
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ubyte re01 = data0[0] + data0[2];
        const npy_ubyte re23 = data0[4] + data0[6];
        const npy_ubyte im13 = data0[1] + data0[3];
        const npy_ubyte im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ubyte *)dataptr[1])[0] += accum_re;
    ((npy_ubyte *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
ubyte_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ubyte accum_re = 0, accum_im = 0;
#else
    npy_ubyte accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_ubyte *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_ubyte *)data0) *
                 (*(npy_ubyte *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_ubyte *)data0) *
                 (*(npy_ubyte *)data1) *
                 (*(npy_ubyte *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_ubyte *)data0)[0];
        accum_im += ((npy_ubyte *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_ubyte *)dataptr[1])[0] += accum_re;
    ((npy_ubyte *)dataptr[1])[1] += accum_im;
#  else
    ((npy_ubyte *)dataptr[nop])[0] += accum_re;
    ((npy_ubyte *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_ubyte *)dataptr[1]) = (accum +
                                    (*((npy_ubyte *)dataptr[1])));
#  else
    *((npy_ubyte *)dataptr[nop]) = (accum +
                                    (*((npy_ubyte *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ubyte_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) *
                                         (*(npy_ubyte *)data1) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) *
                                         (*(npy_ubyte *)data1) *
                                         (*(npy_ubyte *)data2) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        *(npy_ubyte *)dataptr[nop] = (temp +
                                           (*(npy_ubyte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_ubyte *)data_out)[0] = ((npy_ubyte *)data0)[0] +
                                         ((npy_ubyte *)data_out)[0];
        ((npy_ubyte *)data_out)[1] = ((npy_ubyte *)data0)[1] +
                                         ((npy_ubyte *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
ubyte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ubyte *)data_out + 2*6)[0] =
                                    ((npy_ubyte *)data0 + 2*6)[0] +
                                    ((npy_ubyte *)data_out + 2*6)[0];
            ((npy_ubyte *)data_out + 2*6)[1] =
                                    ((npy_ubyte *)data0 + 2*6)[1] +
                                    ((npy_ubyte *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ubyte *)data_out + 2*5)[0] =
                                    ((npy_ubyte *)data0 + 2*5)[0] +
                                    ((npy_ubyte *)data_out + 2*5)[0];
            ((npy_ubyte *)data_out + 2*5)[1] =
                                    ((npy_ubyte *)data0 + 2*5)[1] +
                                    ((npy_ubyte *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ubyte *)data_out + 2*4)[0] =
                                    ((npy_ubyte *)data0 + 2*4)[0] +
                                    ((npy_ubyte *)data_out + 2*4)[0];
            ((npy_ubyte *)data_out + 2*4)[1] =
                                    ((npy_ubyte *)data0 + 2*4)[1] +
                                    ((npy_ubyte *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ubyte *)data_out + 2*3)[0] =
                                    ((npy_ubyte *)data0 + 2*3)[0] +
                                    ((npy_ubyte *)data_out + 2*3)[0];
            ((npy_ubyte *)data_out + 2*3)[1] =
                                    ((npy_ubyte *)data0 + 2*3)[1] +
                                    ((npy_ubyte *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ubyte *)data_out + 2*2)[0] =
                                    ((npy_ubyte *)data0 + 2*2)[0] +
                                    ((npy_ubyte *)data_out + 2*2)[0];
            ((npy_ubyte *)data_out + 2*2)[1] =
                                    ((npy_ubyte *)data0 + 2*2)[1] +
                                    ((npy_ubyte *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ubyte *)data_out + 2*1)[0] =
                                    ((npy_ubyte *)data0 + 2*1)[0] +
                                    ((npy_ubyte *)data_out + 2*1)[0];
            ((npy_ubyte *)data_out + 2*1)[1] =
                                    ((npy_ubyte *)data0 + 2*1)[1] +
                                    ((npy_ubyte *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ubyte *)data_out + 2*0)[0] =
                                    ((npy_ubyte *)data0 + 2*0)[0] +
                                    ((npy_ubyte *)data_out + 2*0)[0];
            ((npy_ubyte *)data_out + 2*0)[1] =
                                    ((npy_ubyte *)data0 + 2*0)[1] +
                                    ((npy_ubyte *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*0)[0] =
                                ((npy_ubyte *)data0 + 2*0)[0] +
                                ((npy_ubyte *)data_out + 2*0)[0];
        ((npy_ubyte *)data_out + 2*0)[1] =
                                ((npy_ubyte *)data0 + 2*0)[1] +
                                ((npy_ubyte *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*1)[0] =
                                ((npy_ubyte *)data0 + 2*1)[0] +
                                ((npy_ubyte *)data_out + 2*1)[0];
        ((npy_ubyte *)data_out + 2*1)[1] =
                                ((npy_ubyte *)data0 + 2*1)[1] +
                                ((npy_ubyte *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*2)[0] =
                                ((npy_ubyte *)data0 + 2*2)[0] +
                                ((npy_ubyte *)data_out + 2*2)[0];
        ((npy_ubyte *)data_out + 2*2)[1] =
                                ((npy_ubyte *)data0 + 2*2)[1] +
                                ((npy_ubyte *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*3)[0] =
                                ((npy_ubyte *)data0 + 2*3)[0] +
                                ((npy_ubyte *)data_out + 2*3)[0];
        ((npy_ubyte *)data_out + 2*3)[1] =
                                ((npy_ubyte *)data0 + 2*3)[1] +
                                ((npy_ubyte *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*4)[0] =
                                ((npy_ubyte *)data0 + 2*4)[0] +
                                ((npy_ubyte *)data_out + 2*4)[0];
        ((npy_ubyte *)data_out + 2*4)[1] =
                                ((npy_ubyte *)data0 + 2*4)[1] +
                                ((npy_ubyte *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*5)[0] =
                                ((npy_ubyte *)data0 + 2*5)[0] +
                                ((npy_ubyte *)data_out + 2*5)[0];
        ((npy_ubyte *)data_out + 2*5)[1] =
                                ((npy_ubyte *)data0 + 2*5)[1] +
                                ((npy_ubyte *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*6)[0] =
                                ((npy_ubyte *)data0 + 2*6)[0] +
                                ((npy_ubyte *)data_out + 2*6)[0];
        ((npy_ubyte *)data_out + 2*6)[1] =
                                ((npy_ubyte *)data0 + 2*6)[1] +
                                ((npy_ubyte *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*7)[0] =
                                ((npy_ubyte *)data0 + 2*7)[0] +
                                ((npy_ubyte *)data_out + 2*7)[0];
        ((npy_ubyte *)data_out + 2*7)[1] =
                                ((npy_ubyte *)data0 + 2*7)[1] +
                                ((npy_ubyte *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ubyte_sum_of_products_muladd(npy_ubyte *data, npy_ubyte *data_out, npy_ubyte scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u8;
    const npyv_u8 v_scalar = npyv_setall_u8(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u8 b0 = npyv_loada_u8(data + vstep * 0);
            npyv_u8 c0 = npyv_loada_u8(data_out + vstep * 0);
            
#line 312
            npyv_u8 b1 = npyv_loada_u8(data + vstep * 1);
            npyv_u8 c1 = npyv_loada_u8(data_out + vstep * 1);
            
#line 312
            npyv_u8 b2 = npyv_loada_u8(data + vstep * 2);
            npyv_u8 c2 = npyv_loada_u8(data_out + vstep * 2);
            
#line 312
            npyv_u8 b3 = npyv_loada_u8(data + vstep * 3);
            npyv_u8 c3 = npyv_loada_u8(data_out + vstep * 3);
            
            #line 318
            npyv_u8 abc0 = npyv_muladd_u8(v_scalar, b0, c0);
            
#line 318
            npyv_u8 abc1 = npyv_muladd_u8(v_scalar, b1, c1);
            
#line 318
            npyv_u8 abc2 = npyv_muladd_u8(v_scalar, b2, c2);
            
#line 318
            npyv_u8 abc3 = npyv_muladd_u8(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u8 b0 = npyv_load_u8(data + vstep * 0);
            npyv_u8 c0 = npyv_load_u8(data_out + vstep * 0);
            
#line 312
            npyv_u8 b1 = npyv_load_u8(data + vstep * 1);
            npyv_u8 c1 = npyv_load_u8(data_out + vstep * 1);
            
#line 312
            npyv_u8 b2 = npyv_load_u8(data + vstep * 2);
            npyv_u8 c2 = npyv_load_u8(data_out + vstep * 2);
            
#line 312
            npyv_u8 b3 = npyv_load_u8(data + vstep * 3);
            npyv_u8 c3 = npyv_load_u8(data_out + vstep * 3);
            
            #line 318
            npyv_u8 abc0 = npyv_muladd_u8(v_scalar, b0, c0);
            
#line 318
            npyv_u8 abc1 = npyv_muladd_u8(v_scalar, b1, c1);
            
#line 318
            npyv_u8 abc2 = npyv_muladd_u8(v_scalar, b2, c2);
            
#line 318
            npyv_u8 abc3 = npyv_muladd_u8(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data, count);
        npyv_u8 b = npyv_load_tillz_u8(data_out, count);
        npyv_store_till_u8(data_out, count, npyv_muladd_u8(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ubyte b0 = (data[0]);
        const npy_ubyte c0 = (data_out[0]);
        
#line 340
        const npy_ubyte b1 = (data[1]);
        const npy_ubyte c1 = (data_out[1]);
        
#line 340
        const npy_ubyte b2 = (data[2]);
        const npy_ubyte c2 = (data_out[2]);
        
#line 340
        const npy_ubyte b3 = (data[3]);
        const npy_ubyte c3 = (data_out[3]);
        
        #line 346
        const npy_ubyte abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ubyte abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ubyte abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ubyte abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ubyte b = (*data);
        const npy_ubyte c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ubyte
}

static void
ubyte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ubyte
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u8;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u8 a0 = npyv_loada_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_loada_u8(data1 + vstep * 0);
            npyv_u8 c0 = npyv_loada_u8(data_out + vstep * 0);
            
#line 390
            npyv_u8 a1 = npyv_loada_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_loada_u8(data1 + vstep * 1);
            npyv_u8 c1 = npyv_loada_u8(data_out + vstep * 1);
            
#line 390
            npyv_u8 a2 = npyv_loada_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_loada_u8(data1 + vstep * 2);
            npyv_u8 c2 = npyv_loada_u8(data_out + vstep * 2);
            
#line 390
            npyv_u8 a3 = npyv_loada_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_loada_u8(data1 + vstep * 3);
            npyv_u8 c3 = npyv_loada_u8(data_out + vstep * 3);
            
            #line 397
            npyv_u8 abc0 = npyv_muladd_u8(a0, b0, c0);
            
#line 397
            npyv_u8 abc1 = npyv_muladd_u8(a1, b1, c1);
            
#line 397
            npyv_u8 abc2 = npyv_muladd_u8(a2, b2, c2);
            
#line 397
            npyv_u8 abc3 = npyv_muladd_u8(a3, b3, c3);
            
            #line 402
            npyv_storea_u8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u8 a0 = npyv_load_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_load_u8(data1 + vstep * 0);
            npyv_u8 c0 = npyv_load_u8(data_out + vstep * 0);
            
#line 390
            npyv_u8 a1 = npyv_load_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_load_u8(data1 + vstep * 1);
            npyv_u8 c1 = npyv_load_u8(data_out + vstep * 1);
            
#line 390
            npyv_u8 a2 = npyv_load_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_load_u8(data1 + vstep * 2);
            npyv_u8 c2 = npyv_load_u8(data_out + vstep * 2);
            
#line 390
            npyv_u8 a3 = npyv_load_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_load_u8(data1 + vstep * 3);
            npyv_u8 c3 = npyv_load_u8(data_out + vstep * 3);
            
            #line 397
            npyv_u8 abc0 = npyv_muladd_u8(a0, b0, c0);
            
#line 397
            npyv_u8 abc1 = npyv_muladd_u8(a1, b1, c1);
            
#line 397
            npyv_u8 abc2 = npyv_muladd_u8(a2, b2, c2);
            
#line 397
            npyv_u8 abc3 = npyv_muladd_u8(a3, b3, c3);
            
            #line 402
            npyv_store_u8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data0, count);
        npyv_u8 b = npyv_load_tillz_u8(data1, count);
        npyv_u8 c = npyv_load_tillz_u8(data_out, count);
        npyv_store_till_u8(data_out, count, npyv_muladd_u8(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ubyte a0 = (data0[0]);
        const npy_ubyte b0 = (data1[0]);
        const npy_ubyte c0 = (data_out[0]);
        
#line 420
        const npy_ubyte a1 = (data0[1]);
        const npy_ubyte b1 = (data1[1]);
        const npy_ubyte c1 = (data_out[1]);
        
#line 420
        const npy_ubyte a2 = (data0[2]);
        const npy_ubyte b2 = (data1[2]);
        const npy_ubyte c2 = (data_out[2]);
        
#line 420
        const npy_ubyte a3 = (data0[3]);
        const npy_ubyte b3 = (data1[3]);
        const npy_ubyte c3 = (data_out[3]);
        
        #line 427
        const npy_ubyte abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ubyte abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ubyte abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ubyte abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ubyte a = (*data0);
        const npy_ubyte b = (*data1);
        const npy_ubyte c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ubyte

}

/* Some extra specializations for the two operand case */
static void
ubyte_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte value0 = (*(npy_ubyte *)dataptr[0]);
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ubyte_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ubyte_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte value1 = (*(npy_ubyte *)dataptr[1]);
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ubyte_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte accum = 0;

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u8;
    npyv_u8 v_accum = npyv_zero_u8();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u8 a0 = npyv_loada_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_loada_u8(data1 + vstep * 0);
            
#line 501
            npyv_u8 a1 = npyv_loada_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_loada_u8(data1 + vstep * 1);
            
#line 501
            npyv_u8 a2 = npyv_loada_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_loada_u8(data1 + vstep * 2);
            
#line 501
            npyv_u8 a3 = npyv_loada_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_loada_u8(data1 + vstep * 3);
            
            npyv_u8 ab3 = npyv_muladd_u8(a3, b3, v_accum);
            npyv_u8 ab2 = npyv_muladd_u8(a2, b2, ab3);
            npyv_u8 ab1 = npyv_muladd_u8(a1, b1, ab2);
                   v_accum = npyv_muladd_u8(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u8 a0 = npyv_load_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_load_u8(data1 + vstep * 0);
            
#line 501
            npyv_u8 a1 = npyv_load_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_load_u8(data1 + vstep * 1);
            
#line 501
            npyv_u8 a2 = npyv_load_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_load_u8(data1 + vstep * 2);
            
#line 501
            npyv_u8 a3 = npyv_load_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_load_u8(data1 + vstep * 3);
            
            npyv_u8 ab3 = npyv_muladd_u8(a3, b3, v_accum);
            npyv_u8 ab2 = npyv_muladd_u8(a2, b2, ab3);
            npyv_u8 ab1 = npyv_muladd_u8(a1, b1, ab2);
                   v_accum = npyv_muladd_u8(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data0, count);
        npyv_u8 b = npyv_load_tillz_u8(data1, count);
        v_accum = npyv_muladd_u8(a, b, v_accum);
    }
    accum = npyv_sum_u8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ubyte ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ubyte ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ubyte ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ubyte ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ubyte a = (*data0);
        const npy_ubyte b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ubyte
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte value0 = (*(npy_ubyte *)dataptr[0]);
    npy_ubyte accum = ubyte_sum_of_arr(data1, count);
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte value1 = (*(npy_ubyte *)dataptr[1]);
    npy_ubyte accum = ubyte_sum_of_arr(data0, count);
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
ubyte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data2 = (npy_ubyte *)dataptr[2];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
ubyte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        *(npy_ubyte *)dataptr[nop] = (temp +
                                           (*(npy_ubyte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ubyte);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ubyte);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ubyte *data = (npy_ubyte *)dataptr[0];
    npy_ubyte accum = ubyte_sum_of_arr(data, count);
    *((npy_ubyte *)dataptr[1]) = (accum + (*((npy_ubyte *)dataptr[1])));
#else
    npy_ubyte accum_re = 0, accum_im = 0;
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ubyte re01 = data0[0] + data0[2];
        const npy_ubyte re23 = data0[4] + data0[6];
        const npy_ubyte im13 = data0[1] + data0[3];
        const npy_ubyte im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ubyte *)dataptr[1])[0] += accum_re;
    ((npy_ubyte *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
ubyte_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ubyte accum_re = 0, accum_im = 0;
#else
    npy_ubyte accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_ubyte *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_ubyte *)data0) *
                 (*(npy_ubyte *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_ubyte *)data0) *
                 (*(npy_ubyte *)data1) *
                 (*(npy_ubyte *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_ubyte *)data0)[0];
        accum_im += ((npy_ubyte *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_ubyte *)dataptr[2])[0] += accum_re;
    ((npy_ubyte *)dataptr[2])[1] += accum_im;
#  else
    ((npy_ubyte *)dataptr[nop])[0] += accum_re;
    ((npy_ubyte *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_ubyte *)dataptr[2]) = (accum +
                                    (*((npy_ubyte *)dataptr[2])));
#  else
    *((npy_ubyte *)dataptr[nop]) = (accum +
                                    (*((npy_ubyte *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ubyte_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) *
                                         (*(npy_ubyte *)data1) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) *
                                         (*(npy_ubyte *)data1) *
                                         (*(npy_ubyte *)data2) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        *(npy_ubyte *)dataptr[nop] = (temp +
                                           (*(npy_ubyte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_ubyte *)data_out)[0] = ((npy_ubyte *)data0)[0] +
                                         ((npy_ubyte *)data_out)[0];
        ((npy_ubyte *)data_out)[1] = ((npy_ubyte *)data0)[1] +
                                         ((npy_ubyte *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
ubyte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ubyte *)data_out + 2*6)[0] =
                                    ((npy_ubyte *)data0 + 2*6)[0] +
                                    ((npy_ubyte *)data_out + 2*6)[0];
            ((npy_ubyte *)data_out + 2*6)[1] =
                                    ((npy_ubyte *)data0 + 2*6)[1] +
                                    ((npy_ubyte *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ubyte *)data_out + 2*5)[0] =
                                    ((npy_ubyte *)data0 + 2*5)[0] +
                                    ((npy_ubyte *)data_out + 2*5)[0];
            ((npy_ubyte *)data_out + 2*5)[1] =
                                    ((npy_ubyte *)data0 + 2*5)[1] +
                                    ((npy_ubyte *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ubyte *)data_out + 2*4)[0] =
                                    ((npy_ubyte *)data0 + 2*4)[0] +
                                    ((npy_ubyte *)data_out + 2*4)[0];
            ((npy_ubyte *)data_out + 2*4)[1] =
                                    ((npy_ubyte *)data0 + 2*4)[1] +
                                    ((npy_ubyte *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ubyte *)data_out + 2*3)[0] =
                                    ((npy_ubyte *)data0 + 2*3)[0] +
                                    ((npy_ubyte *)data_out + 2*3)[0];
            ((npy_ubyte *)data_out + 2*3)[1] =
                                    ((npy_ubyte *)data0 + 2*3)[1] +
                                    ((npy_ubyte *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ubyte *)data_out + 2*2)[0] =
                                    ((npy_ubyte *)data0 + 2*2)[0] +
                                    ((npy_ubyte *)data_out + 2*2)[0];
            ((npy_ubyte *)data_out + 2*2)[1] =
                                    ((npy_ubyte *)data0 + 2*2)[1] +
                                    ((npy_ubyte *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ubyte *)data_out + 2*1)[0] =
                                    ((npy_ubyte *)data0 + 2*1)[0] +
                                    ((npy_ubyte *)data_out + 2*1)[0];
            ((npy_ubyte *)data_out + 2*1)[1] =
                                    ((npy_ubyte *)data0 + 2*1)[1] +
                                    ((npy_ubyte *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ubyte *)data_out + 2*0)[0] =
                                    ((npy_ubyte *)data0 + 2*0)[0] +
                                    ((npy_ubyte *)data_out + 2*0)[0];
            ((npy_ubyte *)data_out + 2*0)[1] =
                                    ((npy_ubyte *)data0 + 2*0)[1] +
                                    ((npy_ubyte *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*0)[0] =
                                ((npy_ubyte *)data0 + 2*0)[0] +
                                ((npy_ubyte *)data_out + 2*0)[0];
        ((npy_ubyte *)data_out + 2*0)[1] =
                                ((npy_ubyte *)data0 + 2*0)[1] +
                                ((npy_ubyte *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*1)[0] =
                                ((npy_ubyte *)data0 + 2*1)[0] +
                                ((npy_ubyte *)data_out + 2*1)[0];
        ((npy_ubyte *)data_out + 2*1)[1] =
                                ((npy_ubyte *)data0 + 2*1)[1] +
                                ((npy_ubyte *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*2)[0] =
                                ((npy_ubyte *)data0 + 2*2)[0] +
                                ((npy_ubyte *)data_out + 2*2)[0];
        ((npy_ubyte *)data_out + 2*2)[1] =
                                ((npy_ubyte *)data0 + 2*2)[1] +
                                ((npy_ubyte *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*3)[0] =
                                ((npy_ubyte *)data0 + 2*3)[0] +
                                ((npy_ubyte *)data_out + 2*3)[0];
        ((npy_ubyte *)data_out + 2*3)[1] =
                                ((npy_ubyte *)data0 + 2*3)[1] +
                                ((npy_ubyte *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*4)[0] =
                                ((npy_ubyte *)data0 + 2*4)[0] +
                                ((npy_ubyte *)data_out + 2*4)[0];
        ((npy_ubyte *)data_out + 2*4)[1] =
                                ((npy_ubyte *)data0 + 2*4)[1] +
                                ((npy_ubyte *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*5)[0] =
                                ((npy_ubyte *)data0 + 2*5)[0] +
                                ((npy_ubyte *)data_out + 2*5)[0];
        ((npy_ubyte *)data_out + 2*5)[1] =
                                ((npy_ubyte *)data0 + 2*5)[1] +
                                ((npy_ubyte *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*6)[0] =
                                ((npy_ubyte *)data0 + 2*6)[0] +
                                ((npy_ubyte *)data_out + 2*6)[0];
        ((npy_ubyte *)data_out + 2*6)[1] =
                                ((npy_ubyte *)data0 + 2*6)[1] +
                                ((npy_ubyte *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*7)[0] =
                                ((npy_ubyte *)data0 + 2*7)[0] +
                                ((npy_ubyte *)data_out + 2*7)[0];
        ((npy_ubyte *)data_out + 2*7)[1] =
                                ((npy_ubyte *)data0 + 2*7)[1] +
                                ((npy_ubyte *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ubyte_sum_of_products_muladd(npy_ubyte *data, npy_ubyte *data_out, npy_ubyte scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u8;
    const npyv_u8 v_scalar = npyv_setall_u8(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u8 b0 = npyv_loada_u8(data + vstep * 0);
            npyv_u8 c0 = npyv_loada_u8(data_out + vstep * 0);
            
#line 312
            npyv_u8 b1 = npyv_loada_u8(data + vstep * 1);
            npyv_u8 c1 = npyv_loada_u8(data_out + vstep * 1);
            
#line 312
            npyv_u8 b2 = npyv_loada_u8(data + vstep * 2);
            npyv_u8 c2 = npyv_loada_u8(data_out + vstep * 2);
            
#line 312
            npyv_u8 b3 = npyv_loada_u8(data + vstep * 3);
            npyv_u8 c3 = npyv_loada_u8(data_out + vstep * 3);
            
            #line 318
            npyv_u8 abc0 = npyv_muladd_u8(v_scalar, b0, c0);
            
#line 318
            npyv_u8 abc1 = npyv_muladd_u8(v_scalar, b1, c1);
            
#line 318
            npyv_u8 abc2 = npyv_muladd_u8(v_scalar, b2, c2);
            
#line 318
            npyv_u8 abc3 = npyv_muladd_u8(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u8 b0 = npyv_load_u8(data + vstep * 0);
            npyv_u8 c0 = npyv_load_u8(data_out + vstep * 0);
            
#line 312
            npyv_u8 b1 = npyv_load_u8(data + vstep * 1);
            npyv_u8 c1 = npyv_load_u8(data_out + vstep * 1);
            
#line 312
            npyv_u8 b2 = npyv_load_u8(data + vstep * 2);
            npyv_u8 c2 = npyv_load_u8(data_out + vstep * 2);
            
#line 312
            npyv_u8 b3 = npyv_load_u8(data + vstep * 3);
            npyv_u8 c3 = npyv_load_u8(data_out + vstep * 3);
            
            #line 318
            npyv_u8 abc0 = npyv_muladd_u8(v_scalar, b0, c0);
            
#line 318
            npyv_u8 abc1 = npyv_muladd_u8(v_scalar, b1, c1);
            
#line 318
            npyv_u8 abc2 = npyv_muladd_u8(v_scalar, b2, c2);
            
#line 318
            npyv_u8 abc3 = npyv_muladd_u8(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data, count);
        npyv_u8 b = npyv_load_tillz_u8(data_out, count);
        npyv_store_till_u8(data_out, count, npyv_muladd_u8(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ubyte b0 = (data[0]);
        const npy_ubyte c0 = (data_out[0]);
        
#line 340
        const npy_ubyte b1 = (data[1]);
        const npy_ubyte c1 = (data_out[1]);
        
#line 340
        const npy_ubyte b2 = (data[2]);
        const npy_ubyte c2 = (data_out[2]);
        
#line 340
        const npy_ubyte b3 = (data[3]);
        const npy_ubyte c3 = (data_out[3]);
        
        #line 346
        const npy_ubyte abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ubyte abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ubyte abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ubyte abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ubyte b = (*data);
        const npy_ubyte c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ubyte
}

static void
ubyte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ubyte
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u8;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u8 a0 = npyv_loada_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_loada_u8(data1 + vstep * 0);
            npyv_u8 c0 = npyv_loada_u8(data_out + vstep * 0);
            
#line 390
            npyv_u8 a1 = npyv_loada_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_loada_u8(data1 + vstep * 1);
            npyv_u8 c1 = npyv_loada_u8(data_out + vstep * 1);
            
#line 390
            npyv_u8 a2 = npyv_loada_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_loada_u8(data1 + vstep * 2);
            npyv_u8 c2 = npyv_loada_u8(data_out + vstep * 2);
            
#line 390
            npyv_u8 a3 = npyv_loada_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_loada_u8(data1 + vstep * 3);
            npyv_u8 c3 = npyv_loada_u8(data_out + vstep * 3);
            
            #line 397
            npyv_u8 abc0 = npyv_muladd_u8(a0, b0, c0);
            
#line 397
            npyv_u8 abc1 = npyv_muladd_u8(a1, b1, c1);
            
#line 397
            npyv_u8 abc2 = npyv_muladd_u8(a2, b2, c2);
            
#line 397
            npyv_u8 abc3 = npyv_muladd_u8(a3, b3, c3);
            
            #line 402
            npyv_storea_u8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u8 a0 = npyv_load_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_load_u8(data1 + vstep * 0);
            npyv_u8 c0 = npyv_load_u8(data_out + vstep * 0);
            
#line 390
            npyv_u8 a1 = npyv_load_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_load_u8(data1 + vstep * 1);
            npyv_u8 c1 = npyv_load_u8(data_out + vstep * 1);
            
#line 390
            npyv_u8 a2 = npyv_load_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_load_u8(data1 + vstep * 2);
            npyv_u8 c2 = npyv_load_u8(data_out + vstep * 2);
            
#line 390
            npyv_u8 a3 = npyv_load_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_load_u8(data1 + vstep * 3);
            npyv_u8 c3 = npyv_load_u8(data_out + vstep * 3);
            
            #line 397
            npyv_u8 abc0 = npyv_muladd_u8(a0, b0, c0);
            
#line 397
            npyv_u8 abc1 = npyv_muladd_u8(a1, b1, c1);
            
#line 397
            npyv_u8 abc2 = npyv_muladd_u8(a2, b2, c2);
            
#line 397
            npyv_u8 abc3 = npyv_muladd_u8(a3, b3, c3);
            
            #line 402
            npyv_store_u8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data0, count);
        npyv_u8 b = npyv_load_tillz_u8(data1, count);
        npyv_u8 c = npyv_load_tillz_u8(data_out, count);
        npyv_store_till_u8(data_out, count, npyv_muladd_u8(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ubyte a0 = (data0[0]);
        const npy_ubyte b0 = (data1[0]);
        const npy_ubyte c0 = (data_out[0]);
        
#line 420
        const npy_ubyte a1 = (data0[1]);
        const npy_ubyte b1 = (data1[1]);
        const npy_ubyte c1 = (data_out[1]);
        
#line 420
        const npy_ubyte a2 = (data0[2]);
        const npy_ubyte b2 = (data1[2]);
        const npy_ubyte c2 = (data_out[2]);
        
#line 420
        const npy_ubyte a3 = (data0[3]);
        const npy_ubyte b3 = (data1[3]);
        const npy_ubyte c3 = (data_out[3]);
        
        #line 427
        const npy_ubyte abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ubyte abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ubyte abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ubyte abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ubyte a = (*data0);
        const npy_ubyte b = (*data1);
        const npy_ubyte c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ubyte

}

/* Some extra specializations for the two operand case */
static void
ubyte_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte value0 = (*(npy_ubyte *)dataptr[0]);
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ubyte_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ubyte_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte value1 = (*(npy_ubyte *)dataptr[1]);
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ubyte_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte accum = 0;

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u8;
    npyv_u8 v_accum = npyv_zero_u8();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u8 a0 = npyv_loada_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_loada_u8(data1 + vstep * 0);
            
#line 501
            npyv_u8 a1 = npyv_loada_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_loada_u8(data1 + vstep * 1);
            
#line 501
            npyv_u8 a2 = npyv_loada_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_loada_u8(data1 + vstep * 2);
            
#line 501
            npyv_u8 a3 = npyv_loada_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_loada_u8(data1 + vstep * 3);
            
            npyv_u8 ab3 = npyv_muladd_u8(a3, b3, v_accum);
            npyv_u8 ab2 = npyv_muladd_u8(a2, b2, ab3);
            npyv_u8 ab1 = npyv_muladd_u8(a1, b1, ab2);
                   v_accum = npyv_muladd_u8(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u8 a0 = npyv_load_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_load_u8(data1 + vstep * 0);
            
#line 501
            npyv_u8 a1 = npyv_load_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_load_u8(data1 + vstep * 1);
            
#line 501
            npyv_u8 a2 = npyv_load_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_load_u8(data1 + vstep * 2);
            
#line 501
            npyv_u8 a3 = npyv_load_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_load_u8(data1 + vstep * 3);
            
            npyv_u8 ab3 = npyv_muladd_u8(a3, b3, v_accum);
            npyv_u8 ab2 = npyv_muladd_u8(a2, b2, ab3);
            npyv_u8 ab1 = npyv_muladd_u8(a1, b1, ab2);
                   v_accum = npyv_muladd_u8(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data0, count);
        npyv_u8 b = npyv_load_tillz_u8(data1, count);
        v_accum = npyv_muladd_u8(a, b, v_accum);
    }
    accum = npyv_sum_u8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ubyte ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ubyte ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ubyte ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ubyte ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ubyte a = (*data0);
        const npy_ubyte b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ubyte
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte value0 = (*(npy_ubyte *)dataptr[0]);
    npy_ubyte accum = ubyte_sum_of_arr(data1, count);
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte value1 = (*(npy_ubyte *)dataptr[1]);
    npy_ubyte accum = ubyte_sum_of_arr(data0, count);
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
ubyte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data2 = (npy_ubyte *)dataptr[2];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
ubyte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        *(npy_ubyte *)dataptr[nop] = (temp +
                                           (*(npy_ubyte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ubyte);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ubyte);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ubyte *data = (npy_ubyte *)dataptr[0];
    npy_ubyte accum = ubyte_sum_of_arr(data, count);
    *((npy_ubyte *)dataptr[1]) = (accum + (*((npy_ubyte *)dataptr[1])));
#else
    npy_ubyte accum_re = 0, accum_im = 0;
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ubyte re01 = data0[0] + data0[2];
        const npy_ubyte re23 = data0[4] + data0[6];
        const npy_ubyte im13 = data0[1] + data0[3];
        const npy_ubyte im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ubyte *)dataptr[1])[0] += accum_re;
    ((npy_ubyte *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
ubyte_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ubyte accum_re = 0, accum_im = 0;
#else
    npy_ubyte accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_ubyte *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_ubyte *)data0) *
                 (*(npy_ubyte *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_ubyte *)data0) *
                 (*(npy_ubyte *)data1) *
                 (*(npy_ubyte *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_ubyte *)data0)[0];
        accum_im += ((npy_ubyte *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_ubyte *)dataptr[3])[0] += accum_re;
    ((npy_ubyte *)dataptr[3])[1] += accum_im;
#  else
    ((npy_ubyte *)dataptr[nop])[0] += accum_re;
    ((npy_ubyte *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_ubyte *)dataptr[3]) = (accum +
                                    (*((npy_ubyte *)dataptr[3])));
#  else
    *((npy_ubyte *)dataptr[nop]) = (accum +
                                    (*((npy_ubyte *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ubyte_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) *
                                         (*(npy_ubyte *)data1) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_ubyte *)data_out = ((*(npy_ubyte *)data0) *
                                         (*(npy_ubyte *)data1) *
                                         (*(npy_ubyte *)data2) +
                                         (*(npy_ubyte *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        *(npy_ubyte *)dataptr[nop] = (temp +
                                           (*(npy_ubyte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_ubyte *)data_out)[0] = ((npy_ubyte *)data0)[0] +
                                         ((npy_ubyte *)data_out)[0];
        ((npy_ubyte *)data_out)[1] = ((npy_ubyte *)data0)[1] +
                                         ((npy_ubyte *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
ubyte_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ubyte *)data_out + 2*6)[0] =
                                    ((npy_ubyte *)data0 + 2*6)[0] +
                                    ((npy_ubyte *)data_out + 2*6)[0];
            ((npy_ubyte *)data_out + 2*6)[1] =
                                    ((npy_ubyte *)data0 + 2*6)[1] +
                                    ((npy_ubyte *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ubyte *)data_out + 2*5)[0] =
                                    ((npy_ubyte *)data0 + 2*5)[0] +
                                    ((npy_ubyte *)data_out + 2*5)[0];
            ((npy_ubyte *)data_out + 2*5)[1] =
                                    ((npy_ubyte *)data0 + 2*5)[1] +
                                    ((npy_ubyte *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ubyte *)data_out + 2*4)[0] =
                                    ((npy_ubyte *)data0 + 2*4)[0] +
                                    ((npy_ubyte *)data_out + 2*4)[0];
            ((npy_ubyte *)data_out + 2*4)[1] =
                                    ((npy_ubyte *)data0 + 2*4)[1] +
                                    ((npy_ubyte *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ubyte *)data_out + 2*3)[0] =
                                    ((npy_ubyte *)data0 + 2*3)[0] +
                                    ((npy_ubyte *)data_out + 2*3)[0];
            ((npy_ubyte *)data_out + 2*3)[1] =
                                    ((npy_ubyte *)data0 + 2*3)[1] +
                                    ((npy_ubyte *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ubyte *)data_out + 2*2)[0] =
                                    ((npy_ubyte *)data0 + 2*2)[0] +
                                    ((npy_ubyte *)data_out + 2*2)[0];
            ((npy_ubyte *)data_out + 2*2)[1] =
                                    ((npy_ubyte *)data0 + 2*2)[1] +
                                    ((npy_ubyte *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ubyte *)data_out + 2*1)[0] =
                                    ((npy_ubyte *)data0 + 2*1)[0] +
                                    ((npy_ubyte *)data_out + 2*1)[0];
            ((npy_ubyte *)data_out + 2*1)[1] =
                                    ((npy_ubyte *)data0 + 2*1)[1] +
                                    ((npy_ubyte *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ubyte *)data_out + 2*0)[0] =
                                    ((npy_ubyte *)data0 + 2*0)[0] +
                                    ((npy_ubyte *)data_out + 2*0)[0];
            ((npy_ubyte *)data_out + 2*0)[1] =
                                    ((npy_ubyte *)data0 + 2*0)[1] +
                                    ((npy_ubyte *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*0)[0] =
                                ((npy_ubyte *)data0 + 2*0)[0] +
                                ((npy_ubyte *)data_out + 2*0)[0];
        ((npy_ubyte *)data_out + 2*0)[1] =
                                ((npy_ubyte *)data0 + 2*0)[1] +
                                ((npy_ubyte *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*1)[0] =
                                ((npy_ubyte *)data0 + 2*1)[0] +
                                ((npy_ubyte *)data_out + 2*1)[0];
        ((npy_ubyte *)data_out + 2*1)[1] =
                                ((npy_ubyte *)data0 + 2*1)[1] +
                                ((npy_ubyte *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*2)[0] =
                                ((npy_ubyte *)data0 + 2*2)[0] +
                                ((npy_ubyte *)data_out + 2*2)[0];
        ((npy_ubyte *)data_out + 2*2)[1] =
                                ((npy_ubyte *)data0 + 2*2)[1] +
                                ((npy_ubyte *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*3)[0] =
                                ((npy_ubyte *)data0 + 2*3)[0] +
                                ((npy_ubyte *)data_out + 2*3)[0];
        ((npy_ubyte *)data_out + 2*3)[1] =
                                ((npy_ubyte *)data0 + 2*3)[1] +
                                ((npy_ubyte *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*4)[0] =
                                ((npy_ubyte *)data0 + 2*4)[0] +
                                ((npy_ubyte *)data_out + 2*4)[0];
        ((npy_ubyte *)data_out + 2*4)[1] =
                                ((npy_ubyte *)data0 + 2*4)[1] +
                                ((npy_ubyte *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*5)[0] =
                                ((npy_ubyte *)data0 + 2*5)[0] +
                                ((npy_ubyte *)data_out + 2*5)[0];
        ((npy_ubyte *)data_out + 2*5)[1] =
                                ((npy_ubyte *)data0 + 2*5)[1] +
                                ((npy_ubyte *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*6)[0] =
                                ((npy_ubyte *)data0 + 2*6)[0] +
                                ((npy_ubyte *)data_out + 2*6)[0];
        ((npy_ubyte *)data_out + 2*6)[1] =
                                ((npy_ubyte *)data0 + 2*6)[1] +
                                ((npy_ubyte *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ubyte *)data_out + 2*7)[0] =
                                ((npy_ubyte *)data0 + 2*7)[0] +
                                ((npy_ubyte *)data_out + 2*7)[0];
        ((npy_ubyte *)data_out + 2*7)[1] =
                                ((npy_ubyte *)data0 + 2*7)[1] +
                                ((npy_ubyte *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ubyte_sum_of_products_muladd(npy_ubyte *data, npy_ubyte *data_out, npy_ubyte scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u8;
    const npyv_u8 v_scalar = npyv_setall_u8(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u8 b0 = npyv_loada_u8(data + vstep * 0);
            npyv_u8 c0 = npyv_loada_u8(data_out + vstep * 0);
            
#line 312
            npyv_u8 b1 = npyv_loada_u8(data + vstep * 1);
            npyv_u8 c1 = npyv_loada_u8(data_out + vstep * 1);
            
#line 312
            npyv_u8 b2 = npyv_loada_u8(data + vstep * 2);
            npyv_u8 c2 = npyv_loada_u8(data_out + vstep * 2);
            
#line 312
            npyv_u8 b3 = npyv_loada_u8(data + vstep * 3);
            npyv_u8 c3 = npyv_loada_u8(data_out + vstep * 3);
            
            #line 318
            npyv_u8 abc0 = npyv_muladd_u8(v_scalar, b0, c0);
            
#line 318
            npyv_u8 abc1 = npyv_muladd_u8(v_scalar, b1, c1);
            
#line 318
            npyv_u8 abc2 = npyv_muladd_u8(v_scalar, b2, c2);
            
#line 318
            npyv_u8 abc3 = npyv_muladd_u8(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u8 b0 = npyv_load_u8(data + vstep * 0);
            npyv_u8 c0 = npyv_load_u8(data_out + vstep * 0);
            
#line 312
            npyv_u8 b1 = npyv_load_u8(data + vstep * 1);
            npyv_u8 c1 = npyv_load_u8(data_out + vstep * 1);
            
#line 312
            npyv_u8 b2 = npyv_load_u8(data + vstep * 2);
            npyv_u8 c2 = npyv_load_u8(data_out + vstep * 2);
            
#line 312
            npyv_u8 b3 = npyv_load_u8(data + vstep * 3);
            npyv_u8 c3 = npyv_load_u8(data_out + vstep * 3);
            
            #line 318
            npyv_u8 abc0 = npyv_muladd_u8(v_scalar, b0, c0);
            
#line 318
            npyv_u8 abc1 = npyv_muladd_u8(v_scalar, b1, c1);
            
#line 318
            npyv_u8 abc2 = npyv_muladd_u8(v_scalar, b2, c2);
            
#line 318
            npyv_u8 abc3 = npyv_muladd_u8(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u8(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u8(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u8(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data, count);
        npyv_u8 b = npyv_load_tillz_u8(data_out, count);
        npyv_store_till_u8(data_out, count, npyv_muladd_u8(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ubyte b0 = (data[0]);
        const npy_ubyte c0 = (data_out[0]);
        
#line 340
        const npy_ubyte b1 = (data[1]);
        const npy_ubyte c1 = (data_out[1]);
        
#line 340
        const npy_ubyte b2 = (data[2]);
        const npy_ubyte c2 = (data_out[2]);
        
#line 340
        const npy_ubyte b3 = (data[3]);
        const npy_ubyte c3 = (data_out[3]);
        
        #line 346
        const npy_ubyte abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ubyte abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ubyte abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ubyte abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ubyte b = (*data);
        const npy_ubyte c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ubyte
}

static void
ubyte_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ubyte
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u8;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u8 a0 = npyv_loada_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_loada_u8(data1 + vstep * 0);
            npyv_u8 c0 = npyv_loada_u8(data_out + vstep * 0);
            
#line 390
            npyv_u8 a1 = npyv_loada_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_loada_u8(data1 + vstep * 1);
            npyv_u8 c1 = npyv_loada_u8(data_out + vstep * 1);
            
#line 390
            npyv_u8 a2 = npyv_loada_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_loada_u8(data1 + vstep * 2);
            npyv_u8 c2 = npyv_loada_u8(data_out + vstep * 2);
            
#line 390
            npyv_u8 a3 = npyv_loada_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_loada_u8(data1 + vstep * 3);
            npyv_u8 c3 = npyv_loada_u8(data_out + vstep * 3);
            
            #line 397
            npyv_u8 abc0 = npyv_muladd_u8(a0, b0, c0);
            
#line 397
            npyv_u8 abc1 = npyv_muladd_u8(a1, b1, c1);
            
#line 397
            npyv_u8 abc2 = npyv_muladd_u8(a2, b2, c2);
            
#line 397
            npyv_u8 abc3 = npyv_muladd_u8(a3, b3, c3);
            
            #line 402
            npyv_storea_u8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u8 a0 = npyv_load_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_load_u8(data1 + vstep * 0);
            npyv_u8 c0 = npyv_load_u8(data_out + vstep * 0);
            
#line 390
            npyv_u8 a1 = npyv_load_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_load_u8(data1 + vstep * 1);
            npyv_u8 c1 = npyv_load_u8(data_out + vstep * 1);
            
#line 390
            npyv_u8 a2 = npyv_load_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_load_u8(data1 + vstep * 2);
            npyv_u8 c2 = npyv_load_u8(data_out + vstep * 2);
            
#line 390
            npyv_u8 a3 = npyv_load_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_load_u8(data1 + vstep * 3);
            npyv_u8 c3 = npyv_load_u8(data_out + vstep * 3);
            
            #line 397
            npyv_u8 abc0 = npyv_muladd_u8(a0, b0, c0);
            
#line 397
            npyv_u8 abc1 = npyv_muladd_u8(a1, b1, c1);
            
#line 397
            npyv_u8 abc2 = npyv_muladd_u8(a2, b2, c2);
            
#line 397
            npyv_u8 abc3 = npyv_muladd_u8(a3, b3, c3);
            
            #line 402
            npyv_store_u8(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u8(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u8(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u8(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data0, count);
        npyv_u8 b = npyv_load_tillz_u8(data1, count);
        npyv_u8 c = npyv_load_tillz_u8(data_out, count);
        npyv_store_till_u8(data_out, count, npyv_muladd_u8(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ubyte a0 = (data0[0]);
        const npy_ubyte b0 = (data1[0]);
        const npy_ubyte c0 = (data_out[0]);
        
#line 420
        const npy_ubyte a1 = (data0[1]);
        const npy_ubyte b1 = (data1[1]);
        const npy_ubyte c1 = (data_out[1]);
        
#line 420
        const npy_ubyte a2 = (data0[2]);
        const npy_ubyte b2 = (data1[2]);
        const npy_ubyte c2 = (data_out[2]);
        
#line 420
        const npy_ubyte a3 = (data0[3]);
        const npy_ubyte b3 = (data1[3]);
        const npy_ubyte c3 = (data_out[3]);
        
        #line 427
        const npy_ubyte abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ubyte abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ubyte abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ubyte abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ubyte a = (*data0);
        const npy_ubyte b = (*data1);
        const npy_ubyte c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ubyte

}

/* Some extra specializations for the two operand case */
static void
ubyte_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte value0 = (*(npy_ubyte *)dataptr[0]);
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ubyte_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ubyte_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte value1 = (*(npy_ubyte *)dataptr[1]);
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ubyte_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte accum = 0;

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ubyte
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u8;
    npyv_u8 v_accum = npyv_zero_u8();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u8 a0 = npyv_loada_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_loada_u8(data1 + vstep * 0);
            
#line 501
            npyv_u8 a1 = npyv_loada_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_loada_u8(data1 + vstep * 1);
            
#line 501
            npyv_u8 a2 = npyv_loada_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_loada_u8(data1 + vstep * 2);
            
#line 501
            npyv_u8 a3 = npyv_loada_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_loada_u8(data1 + vstep * 3);
            
            npyv_u8 ab3 = npyv_muladd_u8(a3, b3, v_accum);
            npyv_u8 ab2 = npyv_muladd_u8(a2, b2, ab3);
            npyv_u8 ab1 = npyv_muladd_u8(a1, b1, ab2);
                   v_accum = npyv_muladd_u8(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u8 a0 = npyv_load_u8(data0 + vstep * 0);
            npyv_u8 b0 = npyv_load_u8(data1 + vstep * 0);
            
#line 501
            npyv_u8 a1 = npyv_load_u8(data0 + vstep * 1);
            npyv_u8 b1 = npyv_load_u8(data1 + vstep * 1);
            
#line 501
            npyv_u8 a2 = npyv_load_u8(data0 + vstep * 2);
            npyv_u8 b2 = npyv_load_u8(data1 + vstep * 2);
            
#line 501
            npyv_u8 a3 = npyv_load_u8(data0 + vstep * 3);
            npyv_u8 b3 = npyv_load_u8(data1 + vstep * 3);
            
            npyv_u8 ab3 = npyv_muladd_u8(a3, b3, v_accum);
            npyv_u8 ab2 = npyv_muladd_u8(a2, b2, ab3);
            npyv_u8 ab1 = npyv_muladd_u8(a1, b1, ab2);
                   v_accum = npyv_muladd_u8(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u8 a = npyv_load_tillz_u8(data0, count);
        npyv_u8 b = npyv_load_tillz_u8(data1, count);
        v_accum = npyv_muladd_u8(a, b, v_accum);
    }
    accum = npyv_sum_u8(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ubyte ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ubyte ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ubyte ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ubyte ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ubyte a = (*data0);
        const npy_ubyte b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ubyte
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte value0 = (*(npy_ubyte *)dataptr[0]);
    npy_ubyte accum = ubyte_sum_of_arr(data1, count);
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte value1 = (*(npy_ubyte *)dataptr[1]);
    npy_ubyte accum = ubyte_sum_of_arr(data0, count);
    *(npy_ubyte *)dataptr[2] = ((*(npy_ubyte *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
ubyte_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
    npy_ubyte *data1 = (npy_ubyte *)dataptr[1];
    npy_ubyte *data2 = (npy_ubyte *)dataptr[2];
    npy_ubyte *data_out = (npy_ubyte *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
ubyte_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        *(npy_ubyte *)dataptr[nop] = (temp +
                                           (*(npy_ubyte *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ubyte);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ubyte *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ubyte);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
ubyte_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ubyte *data = (npy_ubyte *)dataptr[0];
    npy_ubyte accum = ubyte_sum_of_arr(data, count);
    *((npy_ubyte *)dataptr[1]) = (accum + (*((npy_ubyte *)dataptr[1])));
#else
    npy_ubyte accum_re = 0, accum_im = 0;
    npy_ubyte *data0 = (npy_ubyte *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ubyte re01 = data0[0] + data0[2];
        const npy_ubyte re23 = data0[4] + data0[6];
        const npy_ubyte im13 = data0[1] + data0[3];
        const npy_ubyte im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ubyte *)dataptr[1])[0] += accum_re;
    ((npy_ubyte *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
ubyte_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ubyte accum_re = 0, accum_im = 0;
#else
    npy_ubyte accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ubyte_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_ubyte *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_ubyte *)data0) *
                 (*(npy_ubyte *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_ubyte *)data0) *
                 (*(npy_ubyte *)data1) *
                 (*(npy_ubyte *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ubyte temp = (*(npy_ubyte *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ubyte *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_ubyte *)data0)[0];
        accum_im += ((npy_ubyte *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ubyte re, im, tmp;
        int i;
        re = ((npy_ubyte *)dataptr[0])[0];
        im = ((npy_ubyte *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ubyte *)dataptr[i])[0] -
                  im * ((npy_ubyte *)dataptr[i])[1];
            im = re * ((npy_ubyte *)dataptr[i])[1] +
                 im * ((npy_ubyte *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_ubyte *)dataptr[1000])[0] += accum_re;
    ((npy_ubyte *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_ubyte *)dataptr[nop])[0] += accum_re;
    ((npy_ubyte *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_ubyte *)dataptr[1000]) = (accum +
                                    (*((npy_ubyte *)dataptr[1000])));
#  else
    *((npy_ubyte *)dataptr[nop]) = (accum +
                                    (*((npy_ubyte *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_ushort ushort_sum_of_arr(npy_ushort *data, npy_intp count)
{
    npy_ushort accum = 0;
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_u16;
    npyv_u16 v_accum = npyv_zero_u16();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_u16 a0 = npyv_loada_u16(data + vstep * 0);
            
#line 96
            npyv_u16 a1 = npyv_loada_u16(data + vstep * 1);
            
#line 96
            npyv_u16 a2 = npyv_loada_u16(data + vstep * 2);
            
#line 96
            npyv_u16 a3 = npyv_loada_u16(data + vstep * 3);
            
            npyv_u16 a01   = npyv_add_u16(a0, a1);
            npyv_u16 a23   = npyv_add_u16(a2, a3);
            npyv_u16 a0123 = npyv_add_u16(a01, a23);
                     v_accum = npyv_add_u16(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_u16 a0 = npyv_load_u16(data + vstep * 0);
            
#line 96
            npyv_u16 a1 = npyv_load_u16(data + vstep * 1);
            
#line 96
            npyv_u16 a2 = npyv_load_u16(data + vstep * 2);
            
#line 96
            npyv_u16 a3 = npyv_load_u16(data + vstep * 3);
            
            npyv_u16 a01   = npyv_add_u16(a0, a1);
            npyv_u16 a23   = npyv_add_u16(a2, a3);
            npyv_u16 a0123 = npyv_add_u16(a01, a23);
                     v_accum = npyv_add_u16(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data, count);
        v_accum = npyv_add_u16(a, v_accum);
    }
    accum = npyv_sum_u16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_ushort a01 = (*data) + (data[1]);
        const npy_ushort a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_ushort
    return accum;
}
#endif

#line 131
static void
ushort_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) *
                                         (*(npy_ushort *)data1) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) *
                                         (*(npy_ushort *)data1) *
                                         (*(npy_ushort *)data2) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        *(npy_ushort *)dataptr[nop] = (temp +
                                           (*(npy_ushort *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_ushort *)data_out)[0] = ((npy_ushort *)data0)[0] +
                                         ((npy_ushort *)data_out)[0];
        ((npy_ushort *)data_out)[1] = ((npy_ushort *)data0)[1] +
                                         ((npy_ushort *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
ushort_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data_out = (npy_ushort *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ushort *)data_out + 2*6)[0] =
                                    ((npy_ushort *)data0 + 2*6)[0] +
                                    ((npy_ushort *)data_out + 2*6)[0];
            ((npy_ushort *)data_out + 2*6)[1] =
                                    ((npy_ushort *)data0 + 2*6)[1] +
                                    ((npy_ushort *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ushort *)data_out + 2*5)[0] =
                                    ((npy_ushort *)data0 + 2*5)[0] +
                                    ((npy_ushort *)data_out + 2*5)[0];
            ((npy_ushort *)data_out + 2*5)[1] =
                                    ((npy_ushort *)data0 + 2*5)[1] +
                                    ((npy_ushort *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ushort *)data_out + 2*4)[0] =
                                    ((npy_ushort *)data0 + 2*4)[0] +
                                    ((npy_ushort *)data_out + 2*4)[0];
            ((npy_ushort *)data_out + 2*4)[1] =
                                    ((npy_ushort *)data0 + 2*4)[1] +
                                    ((npy_ushort *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ushort *)data_out + 2*3)[0] =
                                    ((npy_ushort *)data0 + 2*3)[0] +
                                    ((npy_ushort *)data_out + 2*3)[0];
            ((npy_ushort *)data_out + 2*3)[1] =
                                    ((npy_ushort *)data0 + 2*3)[1] +
                                    ((npy_ushort *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ushort *)data_out + 2*2)[0] =
                                    ((npy_ushort *)data0 + 2*2)[0] +
                                    ((npy_ushort *)data_out + 2*2)[0];
            ((npy_ushort *)data_out + 2*2)[1] =
                                    ((npy_ushort *)data0 + 2*2)[1] +
                                    ((npy_ushort *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ushort *)data_out + 2*1)[0] =
                                    ((npy_ushort *)data0 + 2*1)[0] +
                                    ((npy_ushort *)data_out + 2*1)[0];
            ((npy_ushort *)data_out + 2*1)[1] =
                                    ((npy_ushort *)data0 + 2*1)[1] +
                                    ((npy_ushort *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ushort *)data_out + 2*0)[0] =
                                    ((npy_ushort *)data0 + 2*0)[0] +
                                    ((npy_ushort *)data_out + 2*0)[0];
            ((npy_ushort *)data_out + 2*0)[1] =
                                    ((npy_ushort *)data0 + 2*0)[1] +
                                    ((npy_ushort *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ushort *)data_out + 2*0)[0] =
                                ((npy_ushort *)data0 + 2*0)[0] +
                                ((npy_ushort *)data_out + 2*0)[0];
        ((npy_ushort *)data_out + 2*0)[1] =
                                ((npy_ushort *)data0 + 2*0)[1] +
                                ((npy_ushort *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ushort *)data_out + 2*1)[0] =
                                ((npy_ushort *)data0 + 2*1)[0] +
                                ((npy_ushort *)data_out + 2*1)[0];
        ((npy_ushort *)data_out + 2*1)[1] =
                                ((npy_ushort *)data0 + 2*1)[1] +
                                ((npy_ushort *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ushort *)data_out + 2*2)[0] =
                                ((npy_ushort *)data0 + 2*2)[0] +
                                ((npy_ushort *)data_out + 2*2)[0];
        ((npy_ushort *)data_out + 2*2)[1] =
                                ((npy_ushort *)data0 + 2*2)[1] +
                                ((npy_ushort *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ushort *)data_out + 2*3)[0] =
                                ((npy_ushort *)data0 + 2*3)[0] +
                                ((npy_ushort *)data_out + 2*3)[0];
        ((npy_ushort *)data_out + 2*3)[1] =
                                ((npy_ushort *)data0 + 2*3)[1] +
                                ((npy_ushort *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ushort *)data_out + 2*4)[0] =
                                ((npy_ushort *)data0 + 2*4)[0] +
                                ((npy_ushort *)data_out + 2*4)[0];
        ((npy_ushort *)data_out + 2*4)[1] =
                                ((npy_ushort *)data0 + 2*4)[1] +
                                ((npy_ushort *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ushort *)data_out + 2*5)[0] =
                                ((npy_ushort *)data0 + 2*5)[0] +
                                ((npy_ushort *)data_out + 2*5)[0];
        ((npy_ushort *)data_out + 2*5)[1] =
                                ((npy_ushort *)data0 + 2*5)[1] +
                                ((npy_ushort *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ushort *)data_out + 2*6)[0] =
                                ((npy_ushort *)data0 + 2*6)[0] +
                                ((npy_ushort *)data_out + 2*6)[0];
        ((npy_ushort *)data_out + 2*6)[1] =
                                ((npy_ushort *)data0 + 2*6)[1] +
                                ((npy_ushort *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ushort *)data_out + 2*7)[0] =
                                ((npy_ushort *)data0 + 2*7)[0] +
                                ((npy_ushort *)data_out + 2*7)[0];
        ((npy_ushort *)data_out + 2*7)[1] =
                                ((npy_ushort *)data0 + 2*7)[1] +
                                ((npy_ushort *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ushort_sum_of_products_muladd(npy_ushort *data, npy_ushort *data_out, npy_ushort scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u16;
    const npyv_u16 v_scalar = npyv_setall_u16(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u16 b0 = npyv_loada_u16(data + vstep * 0);
            npyv_u16 c0 = npyv_loada_u16(data_out + vstep * 0);
            
#line 312
            npyv_u16 b1 = npyv_loada_u16(data + vstep * 1);
            npyv_u16 c1 = npyv_loada_u16(data_out + vstep * 1);
            
#line 312
            npyv_u16 b2 = npyv_loada_u16(data + vstep * 2);
            npyv_u16 c2 = npyv_loada_u16(data_out + vstep * 2);
            
#line 312
            npyv_u16 b3 = npyv_loada_u16(data + vstep * 3);
            npyv_u16 c3 = npyv_loada_u16(data_out + vstep * 3);
            
            #line 318
            npyv_u16 abc0 = npyv_muladd_u16(v_scalar, b0, c0);
            
#line 318
            npyv_u16 abc1 = npyv_muladd_u16(v_scalar, b1, c1);
            
#line 318
            npyv_u16 abc2 = npyv_muladd_u16(v_scalar, b2, c2);
            
#line 318
            npyv_u16 abc3 = npyv_muladd_u16(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u16 b0 = npyv_load_u16(data + vstep * 0);
            npyv_u16 c0 = npyv_load_u16(data_out + vstep * 0);
            
#line 312
            npyv_u16 b1 = npyv_load_u16(data + vstep * 1);
            npyv_u16 c1 = npyv_load_u16(data_out + vstep * 1);
            
#line 312
            npyv_u16 b2 = npyv_load_u16(data + vstep * 2);
            npyv_u16 c2 = npyv_load_u16(data_out + vstep * 2);
            
#line 312
            npyv_u16 b3 = npyv_load_u16(data + vstep * 3);
            npyv_u16 c3 = npyv_load_u16(data_out + vstep * 3);
            
            #line 318
            npyv_u16 abc0 = npyv_muladd_u16(v_scalar, b0, c0);
            
#line 318
            npyv_u16 abc1 = npyv_muladd_u16(v_scalar, b1, c1);
            
#line 318
            npyv_u16 abc2 = npyv_muladd_u16(v_scalar, b2, c2);
            
#line 318
            npyv_u16 abc3 = npyv_muladd_u16(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data, count);
        npyv_u16 b = npyv_load_tillz_u16(data_out, count);
        npyv_store_till_u16(data_out, count, npyv_muladd_u16(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ushort b0 = (data[0]);
        const npy_ushort c0 = (data_out[0]);
        
#line 340
        const npy_ushort b1 = (data[1]);
        const npy_ushort c1 = (data_out[1]);
        
#line 340
        const npy_ushort b2 = (data[2]);
        const npy_ushort c2 = (data_out[2]);
        
#line 340
        const npy_ushort b3 = (data[3]);
        const npy_ushort c3 = (data_out[3]);
        
        #line 346
        const npy_ushort abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ushort abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ushort abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ushort abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ushort b = (*data);
        const npy_ushort c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ushort
}

static void
ushort_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ushort
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u16;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u16 a0 = npyv_loada_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_loada_u16(data1 + vstep * 0);
            npyv_u16 c0 = npyv_loada_u16(data_out + vstep * 0);
            
#line 390
            npyv_u16 a1 = npyv_loada_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_loada_u16(data1 + vstep * 1);
            npyv_u16 c1 = npyv_loada_u16(data_out + vstep * 1);
            
#line 390
            npyv_u16 a2 = npyv_loada_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_loada_u16(data1 + vstep * 2);
            npyv_u16 c2 = npyv_loada_u16(data_out + vstep * 2);
            
#line 390
            npyv_u16 a3 = npyv_loada_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_loada_u16(data1 + vstep * 3);
            npyv_u16 c3 = npyv_loada_u16(data_out + vstep * 3);
            
            #line 397
            npyv_u16 abc0 = npyv_muladd_u16(a0, b0, c0);
            
#line 397
            npyv_u16 abc1 = npyv_muladd_u16(a1, b1, c1);
            
#line 397
            npyv_u16 abc2 = npyv_muladd_u16(a2, b2, c2);
            
#line 397
            npyv_u16 abc3 = npyv_muladd_u16(a3, b3, c3);
            
            #line 402
            npyv_storea_u16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u16 a0 = npyv_load_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_load_u16(data1 + vstep * 0);
            npyv_u16 c0 = npyv_load_u16(data_out + vstep * 0);
            
#line 390
            npyv_u16 a1 = npyv_load_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_load_u16(data1 + vstep * 1);
            npyv_u16 c1 = npyv_load_u16(data_out + vstep * 1);
            
#line 390
            npyv_u16 a2 = npyv_load_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_load_u16(data1 + vstep * 2);
            npyv_u16 c2 = npyv_load_u16(data_out + vstep * 2);
            
#line 390
            npyv_u16 a3 = npyv_load_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_load_u16(data1 + vstep * 3);
            npyv_u16 c3 = npyv_load_u16(data_out + vstep * 3);
            
            #line 397
            npyv_u16 abc0 = npyv_muladd_u16(a0, b0, c0);
            
#line 397
            npyv_u16 abc1 = npyv_muladd_u16(a1, b1, c1);
            
#line 397
            npyv_u16 abc2 = npyv_muladd_u16(a2, b2, c2);
            
#line 397
            npyv_u16 abc3 = npyv_muladd_u16(a3, b3, c3);
            
            #line 402
            npyv_store_u16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data0, count);
        npyv_u16 b = npyv_load_tillz_u16(data1, count);
        npyv_u16 c = npyv_load_tillz_u16(data_out, count);
        npyv_store_till_u16(data_out, count, npyv_muladd_u16(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ushort a0 = (data0[0]);
        const npy_ushort b0 = (data1[0]);
        const npy_ushort c0 = (data_out[0]);
        
#line 420
        const npy_ushort a1 = (data0[1]);
        const npy_ushort b1 = (data1[1]);
        const npy_ushort c1 = (data_out[1]);
        
#line 420
        const npy_ushort a2 = (data0[2]);
        const npy_ushort b2 = (data1[2]);
        const npy_ushort c2 = (data_out[2]);
        
#line 420
        const npy_ushort a3 = (data0[3]);
        const npy_ushort b3 = (data1[3]);
        const npy_ushort c3 = (data_out[3]);
        
        #line 427
        const npy_ushort abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ushort abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ushort abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ushort abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ushort a = (*data0);
        const npy_ushort b = (*data1);
        const npy_ushort c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ushort

}

/* Some extra specializations for the two operand case */
static void
ushort_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort value0 = (*(npy_ushort *)dataptr[0]);
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ushort_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ushort_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort value1 = (*(npy_ushort *)dataptr[1]);
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ushort_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort accum = 0;

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u16;
    npyv_u16 v_accum = npyv_zero_u16();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u16 a0 = npyv_loada_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_loada_u16(data1 + vstep * 0);
            
#line 501
            npyv_u16 a1 = npyv_loada_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_loada_u16(data1 + vstep * 1);
            
#line 501
            npyv_u16 a2 = npyv_loada_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_loada_u16(data1 + vstep * 2);
            
#line 501
            npyv_u16 a3 = npyv_loada_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_loada_u16(data1 + vstep * 3);
            
            npyv_u16 ab3 = npyv_muladd_u16(a3, b3, v_accum);
            npyv_u16 ab2 = npyv_muladd_u16(a2, b2, ab3);
            npyv_u16 ab1 = npyv_muladd_u16(a1, b1, ab2);
                   v_accum = npyv_muladd_u16(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u16 a0 = npyv_load_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_load_u16(data1 + vstep * 0);
            
#line 501
            npyv_u16 a1 = npyv_load_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_load_u16(data1 + vstep * 1);
            
#line 501
            npyv_u16 a2 = npyv_load_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_load_u16(data1 + vstep * 2);
            
#line 501
            npyv_u16 a3 = npyv_load_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_load_u16(data1 + vstep * 3);
            
            npyv_u16 ab3 = npyv_muladd_u16(a3, b3, v_accum);
            npyv_u16 ab2 = npyv_muladd_u16(a2, b2, ab3);
            npyv_u16 ab1 = npyv_muladd_u16(a1, b1, ab2);
                   v_accum = npyv_muladd_u16(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data0, count);
        npyv_u16 b = npyv_load_tillz_u16(data1, count);
        v_accum = npyv_muladd_u16(a, b, v_accum);
    }
    accum = npyv_sum_u16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ushort ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ushort ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ushort ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ushort ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ushort a = (*data0);
        const npy_ushort b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ushort
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort value0 = (*(npy_ushort *)dataptr[0]);
    npy_ushort accum = ushort_sum_of_arr(data1, count);
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort value1 = (*(npy_ushort *)dataptr[1]);
    npy_ushort accum = ushort_sum_of_arr(data0, count);
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
ushort_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data2 = (npy_ushort *)dataptr[2];
    npy_ushort *data_out = (npy_ushort *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
ushort_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        *(npy_ushort *)dataptr[nop] = (temp +
                                           (*(npy_ushort *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ushort);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ushort);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ushort *data = (npy_ushort *)dataptr[0];
    npy_ushort accum = ushort_sum_of_arr(data, count);
    *((npy_ushort *)dataptr[1]) = (accum + (*((npy_ushort *)dataptr[1])));
#else
    npy_ushort accum_re = 0, accum_im = 0;
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ushort re01 = data0[0] + data0[2];
        const npy_ushort re23 = data0[4] + data0[6];
        const npy_ushort im13 = data0[1] + data0[3];
        const npy_ushort im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ushort *)dataptr[1])[0] += accum_re;
    ((npy_ushort *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
ushort_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ushort accum_re = 0, accum_im = 0;
#else
    npy_ushort accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_ushort *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_ushort *)data0) *
                 (*(npy_ushort *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_ushort *)data0) *
                 (*(npy_ushort *)data1) *
                 (*(npy_ushort *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_ushort *)data0)[0];
        accum_im += ((npy_ushort *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_ushort *)dataptr[1])[0] += accum_re;
    ((npy_ushort *)dataptr[1])[1] += accum_im;
#  else
    ((npy_ushort *)dataptr[nop])[0] += accum_re;
    ((npy_ushort *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_ushort *)dataptr[1]) = (accum +
                                    (*((npy_ushort *)dataptr[1])));
#  else
    *((npy_ushort *)dataptr[nop]) = (accum +
                                    (*((npy_ushort *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ushort_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) *
                                         (*(npy_ushort *)data1) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) *
                                         (*(npy_ushort *)data1) *
                                         (*(npy_ushort *)data2) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        *(npy_ushort *)dataptr[nop] = (temp +
                                           (*(npy_ushort *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_ushort *)data_out)[0] = ((npy_ushort *)data0)[0] +
                                         ((npy_ushort *)data_out)[0];
        ((npy_ushort *)data_out)[1] = ((npy_ushort *)data0)[1] +
                                         ((npy_ushort *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
ushort_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data_out = (npy_ushort *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ushort *)data_out + 2*6)[0] =
                                    ((npy_ushort *)data0 + 2*6)[0] +
                                    ((npy_ushort *)data_out + 2*6)[0];
            ((npy_ushort *)data_out + 2*6)[1] =
                                    ((npy_ushort *)data0 + 2*6)[1] +
                                    ((npy_ushort *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ushort *)data_out + 2*5)[0] =
                                    ((npy_ushort *)data0 + 2*5)[0] +
                                    ((npy_ushort *)data_out + 2*5)[0];
            ((npy_ushort *)data_out + 2*5)[1] =
                                    ((npy_ushort *)data0 + 2*5)[1] +
                                    ((npy_ushort *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ushort *)data_out + 2*4)[0] =
                                    ((npy_ushort *)data0 + 2*4)[0] +
                                    ((npy_ushort *)data_out + 2*4)[0];
            ((npy_ushort *)data_out + 2*4)[1] =
                                    ((npy_ushort *)data0 + 2*4)[1] +
                                    ((npy_ushort *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ushort *)data_out + 2*3)[0] =
                                    ((npy_ushort *)data0 + 2*3)[0] +
                                    ((npy_ushort *)data_out + 2*3)[0];
            ((npy_ushort *)data_out + 2*3)[1] =
                                    ((npy_ushort *)data0 + 2*3)[1] +
                                    ((npy_ushort *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ushort *)data_out + 2*2)[0] =
                                    ((npy_ushort *)data0 + 2*2)[0] +
                                    ((npy_ushort *)data_out + 2*2)[0];
            ((npy_ushort *)data_out + 2*2)[1] =
                                    ((npy_ushort *)data0 + 2*2)[1] +
                                    ((npy_ushort *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ushort *)data_out + 2*1)[0] =
                                    ((npy_ushort *)data0 + 2*1)[0] +
                                    ((npy_ushort *)data_out + 2*1)[0];
            ((npy_ushort *)data_out + 2*1)[1] =
                                    ((npy_ushort *)data0 + 2*1)[1] +
                                    ((npy_ushort *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ushort *)data_out + 2*0)[0] =
                                    ((npy_ushort *)data0 + 2*0)[0] +
                                    ((npy_ushort *)data_out + 2*0)[0];
            ((npy_ushort *)data_out + 2*0)[1] =
                                    ((npy_ushort *)data0 + 2*0)[1] +
                                    ((npy_ushort *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ushort *)data_out + 2*0)[0] =
                                ((npy_ushort *)data0 + 2*0)[0] +
                                ((npy_ushort *)data_out + 2*0)[0];
        ((npy_ushort *)data_out + 2*0)[1] =
                                ((npy_ushort *)data0 + 2*0)[1] +
                                ((npy_ushort *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ushort *)data_out + 2*1)[0] =
                                ((npy_ushort *)data0 + 2*1)[0] +
                                ((npy_ushort *)data_out + 2*1)[0];
        ((npy_ushort *)data_out + 2*1)[1] =
                                ((npy_ushort *)data0 + 2*1)[1] +
                                ((npy_ushort *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ushort *)data_out + 2*2)[0] =
                                ((npy_ushort *)data0 + 2*2)[0] +
                                ((npy_ushort *)data_out + 2*2)[0];
        ((npy_ushort *)data_out + 2*2)[1] =
                                ((npy_ushort *)data0 + 2*2)[1] +
                                ((npy_ushort *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ushort *)data_out + 2*3)[0] =
                                ((npy_ushort *)data0 + 2*3)[0] +
                                ((npy_ushort *)data_out + 2*3)[0];
        ((npy_ushort *)data_out + 2*3)[1] =
                                ((npy_ushort *)data0 + 2*3)[1] +
                                ((npy_ushort *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ushort *)data_out + 2*4)[0] =
                                ((npy_ushort *)data0 + 2*4)[0] +
                                ((npy_ushort *)data_out + 2*4)[0];
        ((npy_ushort *)data_out + 2*4)[1] =
                                ((npy_ushort *)data0 + 2*4)[1] +
                                ((npy_ushort *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ushort *)data_out + 2*5)[0] =
                                ((npy_ushort *)data0 + 2*5)[0] +
                                ((npy_ushort *)data_out + 2*5)[0];
        ((npy_ushort *)data_out + 2*5)[1] =
                                ((npy_ushort *)data0 + 2*5)[1] +
                                ((npy_ushort *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ushort *)data_out + 2*6)[0] =
                                ((npy_ushort *)data0 + 2*6)[0] +
                                ((npy_ushort *)data_out + 2*6)[0];
        ((npy_ushort *)data_out + 2*6)[1] =
                                ((npy_ushort *)data0 + 2*6)[1] +
                                ((npy_ushort *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ushort *)data_out + 2*7)[0] =
                                ((npy_ushort *)data0 + 2*7)[0] +
                                ((npy_ushort *)data_out + 2*7)[0];
        ((npy_ushort *)data_out + 2*7)[1] =
                                ((npy_ushort *)data0 + 2*7)[1] +
                                ((npy_ushort *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ushort_sum_of_products_muladd(npy_ushort *data, npy_ushort *data_out, npy_ushort scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u16;
    const npyv_u16 v_scalar = npyv_setall_u16(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u16 b0 = npyv_loada_u16(data + vstep * 0);
            npyv_u16 c0 = npyv_loada_u16(data_out + vstep * 0);
            
#line 312
            npyv_u16 b1 = npyv_loada_u16(data + vstep * 1);
            npyv_u16 c1 = npyv_loada_u16(data_out + vstep * 1);
            
#line 312
            npyv_u16 b2 = npyv_loada_u16(data + vstep * 2);
            npyv_u16 c2 = npyv_loada_u16(data_out + vstep * 2);
            
#line 312
            npyv_u16 b3 = npyv_loada_u16(data + vstep * 3);
            npyv_u16 c3 = npyv_loada_u16(data_out + vstep * 3);
            
            #line 318
            npyv_u16 abc0 = npyv_muladd_u16(v_scalar, b0, c0);
            
#line 318
            npyv_u16 abc1 = npyv_muladd_u16(v_scalar, b1, c1);
            
#line 318
            npyv_u16 abc2 = npyv_muladd_u16(v_scalar, b2, c2);
            
#line 318
            npyv_u16 abc3 = npyv_muladd_u16(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u16 b0 = npyv_load_u16(data + vstep * 0);
            npyv_u16 c0 = npyv_load_u16(data_out + vstep * 0);
            
#line 312
            npyv_u16 b1 = npyv_load_u16(data + vstep * 1);
            npyv_u16 c1 = npyv_load_u16(data_out + vstep * 1);
            
#line 312
            npyv_u16 b2 = npyv_load_u16(data + vstep * 2);
            npyv_u16 c2 = npyv_load_u16(data_out + vstep * 2);
            
#line 312
            npyv_u16 b3 = npyv_load_u16(data + vstep * 3);
            npyv_u16 c3 = npyv_load_u16(data_out + vstep * 3);
            
            #line 318
            npyv_u16 abc0 = npyv_muladd_u16(v_scalar, b0, c0);
            
#line 318
            npyv_u16 abc1 = npyv_muladd_u16(v_scalar, b1, c1);
            
#line 318
            npyv_u16 abc2 = npyv_muladd_u16(v_scalar, b2, c2);
            
#line 318
            npyv_u16 abc3 = npyv_muladd_u16(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data, count);
        npyv_u16 b = npyv_load_tillz_u16(data_out, count);
        npyv_store_till_u16(data_out, count, npyv_muladd_u16(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ushort b0 = (data[0]);
        const npy_ushort c0 = (data_out[0]);
        
#line 340
        const npy_ushort b1 = (data[1]);
        const npy_ushort c1 = (data_out[1]);
        
#line 340
        const npy_ushort b2 = (data[2]);
        const npy_ushort c2 = (data_out[2]);
        
#line 340
        const npy_ushort b3 = (data[3]);
        const npy_ushort c3 = (data_out[3]);
        
        #line 346
        const npy_ushort abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ushort abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ushort abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ushort abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ushort b = (*data);
        const npy_ushort c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ushort
}

static void
ushort_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ushort
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u16;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u16 a0 = npyv_loada_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_loada_u16(data1 + vstep * 0);
            npyv_u16 c0 = npyv_loada_u16(data_out + vstep * 0);
            
#line 390
            npyv_u16 a1 = npyv_loada_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_loada_u16(data1 + vstep * 1);
            npyv_u16 c1 = npyv_loada_u16(data_out + vstep * 1);
            
#line 390
            npyv_u16 a2 = npyv_loada_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_loada_u16(data1 + vstep * 2);
            npyv_u16 c2 = npyv_loada_u16(data_out + vstep * 2);
            
#line 390
            npyv_u16 a3 = npyv_loada_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_loada_u16(data1 + vstep * 3);
            npyv_u16 c3 = npyv_loada_u16(data_out + vstep * 3);
            
            #line 397
            npyv_u16 abc0 = npyv_muladd_u16(a0, b0, c0);
            
#line 397
            npyv_u16 abc1 = npyv_muladd_u16(a1, b1, c1);
            
#line 397
            npyv_u16 abc2 = npyv_muladd_u16(a2, b2, c2);
            
#line 397
            npyv_u16 abc3 = npyv_muladd_u16(a3, b3, c3);
            
            #line 402
            npyv_storea_u16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u16 a0 = npyv_load_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_load_u16(data1 + vstep * 0);
            npyv_u16 c0 = npyv_load_u16(data_out + vstep * 0);
            
#line 390
            npyv_u16 a1 = npyv_load_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_load_u16(data1 + vstep * 1);
            npyv_u16 c1 = npyv_load_u16(data_out + vstep * 1);
            
#line 390
            npyv_u16 a2 = npyv_load_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_load_u16(data1 + vstep * 2);
            npyv_u16 c2 = npyv_load_u16(data_out + vstep * 2);
            
#line 390
            npyv_u16 a3 = npyv_load_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_load_u16(data1 + vstep * 3);
            npyv_u16 c3 = npyv_load_u16(data_out + vstep * 3);
            
            #line 397
            npyv_u16 abc0 = npyv_muladd_u16(a0, b0, c0);
            
#line 397
            npyv_u16 abc1 = npyv_muladd_u16(a1, b1, c1);
            
#line 397
            npyv_u16 abc2 = npyv_muladd_u16(a2, b2, c2);
            
#line 397
            npyv_u16 abc3 = npyv_muladd_u16(a3, b3, c3);
            
            #line 402
            npyv_store_u16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data0, count);
        npyv_u16 b = npyv_load_tillz_u16(data1, count);
        npyv_u16 c = npyv_load_tillz_u16(data_out, count);
        npyv_store_till_u16(data_out, count, npyv_muladd_u16(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ushort a0 = (data0[0]);
        const npy_ushort b0 = (data1[0]);
        const npy_ushort c0 = (data_out[0]);
        
#line 420
        const npy_ushort a1 = (data0[1]);
        const npy_ushort b1 = (data1[1]);
        const npy_ushort c1 = (data_out[1]);
        
#line 420
        const npy_ushort a2 = (data0[2]);
        const npy_ushort b2 = (data1[2]);
        const npy_ushort c2 = (data_out[2]);
        
#line 420
        const npy_ushort a3 = (data0[3]);
        const npy_ushort b3 = (data1[3]);
        const npy_ushort c3 = (data_out[3]);
        
        #line 427
        const npy_ushort abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ushort abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ushort abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ushort abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ushort a = (*data0);
        const npy_ushort b = (*data1);
        const npy_ushort c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ushort

}

/* Some extra specializations for the two operand case */
static void
ushort_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort value0 = (*(npy_ushort *)dataptr[0]);
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ushort_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ushort_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort value1 = (*(npy_ushort *)dataptr[1]);
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ushort_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort accum = 0;

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u16;
    npyv_u16 v_accum = npyv_zero_u16();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u16 a0 = npyv_loada_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_loada_u16(data1 + vstep * 0);
            
#line 501
            npyv_u16 a1 = npyv_loada_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_loada_u16(data1 + vstep * 1);
            
#line 501
            npyv_u16 a2 = npyv_loada_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_loada_u16(data1 + vstep * 2);
            
#line 501
            npyv_u16 a3 = npyv_loada_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_loada_u16(data1 + vstep * 3);
            
            npyv_u16 ab3 = npyv_muladd_u16(a3, b3, v_accum);
            npyv_u16 ab2 = npyv_muladd_u16(a2, b2, ab3);
            npyv_u16 ab1 = npyv_muladd_u16(a1, b1, ab2);
                   v_accum = npyv_muladd_u16(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u16 a0 = npyv_load_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_load_u16(data1 + vstep * 0);
            
#line 501
            npyv_u16 a1 = npyv_load_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_load_u16(data1 + vstep * 1);
            
#line 501
            npyv_u16 a2 = npyv_load_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_load_u16(data1 + vstep * 2);
            
#line 501
            npyv_u16 a3 = npyv_load_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_load_u16(data1 + vstep * 3);
            
            npyv_u16 ab3 = npyv_muladd_u16(a3, b3, v_accum);
            npyv_u16 ab2 = npyv_muladd_u16(a2, b2, ab3);
            npyv_u16 ab1 = npyv_muladd_u16(a1, b1, ab2);
                   v_accum = npyv_muladd_u16(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data0, count);
        npyv_u16 b = npyv_load_tillz_u16(data1, count);
        v_accum = npyv_muladd_u16(a, b, v_accum);
    }
    accum = npyv_sum_u16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ushort ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ushort ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ushort ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ushort ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ushort a = (*data0);
        const npy_ushort b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ushort
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort value0 = (*(npy_ushort *)dataptr[0]);
    npy_ushort accum = ushort_sum_of_arr(data1, count);
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort value1 = (*(npy_ushort *)dataptr[1]);
    npy_ushort accum = ushort_sum_of_arr(data0, count);
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
ushort_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data2 = (npy_ushort *)dataptr[2];
    npy_ushort *data_out = (npy_ushort *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
ushort_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        *(npy_ushort *)dataptr[nop] = (temp +
                                           (*(npy_ushort *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ushort);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ushort);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ushort *data = (npy_ushort *)dataptr[0];
    npy_ushort accum = ushort_sum_of_arr(data, count);
    *((npy_ushort *)dataptr[1]) = (accum + (*((npy_ushort *)dataptr[1])));
#else
    npy_ushort accum_re = 0, accum_im = 0;
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ushort re01 = data0[0] + data0[2];
        const npy_ushort re23 = data0[4] + data0[6];
        const npy_ushort im13 = data0[1] + data0[3];
        const npy_ushort im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ushort *)dataptr[1])[0] += accum_re;
    ((npy_ushort *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
ushort_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ushort accum_re = 0, accum_im = 0;
#else
    npy_ushort accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_ushort *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_ushort *)data0) *
                 (*(npy_ushort *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_ushort *)data0) *
                 (*(npy_ushort *)data1) *
                 (*(npy_ushort *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_ushort *)data0)[0];
        accum_im += ((npy_ushort *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_ushort *)dataptr[2])[0] += accum_re;
    ((npy_ushort *)dataptr[2])[1] += accum_im;
#  else
    ((npy_ushort *)dataptr[nop])[0] += accum_re;
    ((npy_ushort *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_ushort *)dataptr[2]) = (accum +
                                    (*((npy_ushort *)dataptr[2])));
#  else
    *((npy_ushort *)dataptr[nop]) = (accum +
                                    (*((npy_ushort *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ushort_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) *
                                         (*(npy_ushort *)data1) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) *
                                         (*(npy_ushort *)data1) *
                                         (*(npy_ushort *)data2) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        *(npy_ushort *)dataptr[nop] = (temp +
                                           (*(npy_ushort *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_ushort *)data_out)[0] = ((npy_ushort *)data0)[0] +
                                         ((npy_ushort *)data_out)[0];
        ((npy_ushort *)data_out)[1] = ((npy_ushort *)data0)[1] +
                                         ((npy_ushort *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
ushort_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data_out = (npy_ushort *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ushort *)data_out + 2*6)[0] =
                                    ((npy_ushort *)data0 + 2*6)[0] +
                                    ((npy_ushort *)data_out + 2*6)[0];
            ((npy_ushort *)data_out + 2*6)[1] =
                                    ((npy_ushort *)data0 + 2*6)[1] +
                                    ((npy_ushort *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ushort *)data_out + 2*5)[0] =
                                    ((npy_ushort *)data0 + 2*5)[0] +
                                    ((npy_ushort *)data_out + 2*5)[0];
            ((npy_ushort *)data_out + 2*5)[1] =
                                    ((npy_ushort *)data0 + 2*5)[1] +
                                    ((npy_ushort *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ushort *)data_out + 2*4)[0] =
                                    ((npy_ushort *)data0 + 2*4)[0] +
                                    ((npy_ushort *)data_out + 2*4)[0];
            ((npy_ushort *)data_out + 2*4)[1] =
                                    ((npy_ushort *)data0 + 2*4)[1] +
                                    ((npy_ushort *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ushort *)data_out + 2*3)[0] =
                                    ((npy_ushort *)data0 + 2*3)[0] +
                                    ((npy_ushort *)data_out + 2*3)[0];
            ((npy_ushort *)data_out + 2*3)[1] =
                                    ((npy_ushort *)data0 + 2*3)[1] +
                                    ((npy_ushort *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ushort *)data_out + 2*2)[0] =
                                    ((npy_ushort *)data0 + 2*2)[0] +
                                    ((npy_ushort *)data_out + 2*2)[0];
            ((npy_ushort *)data_out + 2*2)[1] =
                                    ((npy_ushort *)data0 + 2*2)[1] +
                                    ((npy_ushort *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ushort *)data_out + 2*1)[0] =
                                    ((npy_ushort *)data0 + 2*1)[0] +
                                    ((npy_ushort *)data_out + 2*1)[0];
            ((npy_ushort *)data_out + 2*1)[1] =
                                    ((npy_ushort *)data0 + 2*1)[1] +
                                    ((npy_ushort *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ushort *)data_out + 2*0)[0] =
                                    ((npy_ushort *)data0 + 2*0)[0] +
                                    ((npy_ushort *)data_out + 2*0)[0];
            ((npy_ushort *)data_out + 2*0)[1] =
                                    ((npy_ushort *)data0 + 2*0)[1] +
                                    ((npy_ushort *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ushort *)data_out + 2*0)[0] =
                                ((npy_ushort *)data0 + 2*0)[0] +
                                ((npy_ushort *)data_out + 2*0)[0];
        ((npy_ushort *)data_out + 2*0)[1] =
                                ((npy_ushort *)data0 + 2*0)[1] +
                                ((npy_ushort *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ushort *)data_out + 2*1)[0] =
                                ((npy_ushort *)data0 + 2*1)[0] +
                                ((npy_ushort *)data_out + 2*1)[0];
        ((npy_ushort *)data_out + 2*1)[1] =
                                ((npy_ushort *)data0 + 2*1)[1] +
                                ((npy_ushort *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ushort *)data_out + 2*2)[0] =
                                ((npy_ushort *)data0 + 2*2)[0] +
                                ((npy_ushort *)data_out + 2*2)[0];
        ((npy_ushort *)data_out + 2*2)[1] =
                                ((npy_ushort *)data0 + 2*2)[1] +
                                ((npy_ushort *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ushort *)data_out + 2*3)[0] =
                                ((npy_ushort *)data0 + 2*3)[0] +
                                ((npy_ushort *)data_out + 2*3)[0];
        ((npy_ushort *)data_out + 2*3)[1] =
                                ((npy_ushort *)data0 + 2*3)[1] +
                                ((npy_ushort *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ushort *)data_out + 2*4)[0] =
                                ((npy_ushort *)data0 + 2*4)[0] +
                                ((npy_ushort *)data_out + 2*4)[0];
        ((npy_ushort *)data_out + 2*4)[1] =
                                ((npy_ushort *)data0 + 2*4)[1] +
                                ((npy_ushort *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ushort *)data_out + 2*5)[0] =
                                ((npy_ushort *)data0 + 2*5)[0] +
                                ((npy_ushort *)data_out + 2*5)[0];
        ((npy_ushort *)data_out + 2*5)[1] =
                                ((npy_ushort *)data0 + 2*5)[1] +
                                ((npy_ushort *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ushort *)data_out + 2*6)[0] =
                                ((npy_ushort *)data0 + 2*6)[0] +
                                ((npy_ushort *)data_out + 2*6)[0];
        ((npy_ushort *)data_out + 2*6)[1] =
                                ((npy_ushort *)data0 + 2*6)[1] +
                                ((npy_ushort *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ushort *)data_out + 2*7)[0] =
                                ((npy_ushort *)data0 + 2*7)[0] +
                                ((npy_ushort *)data_out + 2*7)[0];
        ((npy_ushort *)data_out + 2*7)[1] =
                                ((npy_ushort *)data0 + 2*7)[1] +
                                ((npy_ushort *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ushort_sum_of_products_muladd(npy_ushort *data, npy_ushort *data_out, npy_ushort scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u16;
    const npyv_u16 v_scalar = npyv_setall_u16(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u16 b0 = npyv_loada_u16(data + vstep * 0);
            npyv_u16 c0 = npyv_loada_u16(data_out + vstep * 0);
            
#line 312
            npyv_u16 b1 = npyv_loada_u16(data + vstep * 1);
            npyv_u16 c1 = npyv_loada_u16(data_out + vstep * 1);
            
#line 312
            npyv_u16 b2 = npyv_loada_u16(data + vstep * 2);
            npyv_u16 c2 = npyv_loada_u16(data_out + vstep * 2);
            
#line 312
            npyv_u16 b3 = npyv_loada_u16(data + vstep * 3);
            npyv_u16 c3 = npyv_loada_u16(data_out + vstep * 3);
            
            #line 318
            npyv_u16 abc0 = npyv_muladd_u16(v_scalar, b0, c0);
            
#line 318
            npyv_u16 abc1 = npyv_muladd_u16(v_scalar, b1, c1);
            
#line 318
            npyv_u16 abc2 = npyv_muladd_u16(v_scalar, b2, c2);
            
#line 318
            npyv_u16 abc3 = npyv_muladd_u16(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u16 b0 = npyv_load_u16(data + vstep * 0);
            npyv_u16 c0 = npyv_load_u16(data_out + vstep * 0);
            
#line 312
            npyv_u16 b1 = npyv_load_u16(data + vstep * 1);
            npyv_u16 c1 = npyv_load_u16(data_out + vstep * 1);
            
#line 312
            npyv_u16 b2 = npyv_load_u16(data + vstep * 2);
            npyv_u16 c2 = npyv_load_u16(data_out + vstep * 2);
            
#line 312
            npyv_u16 b3 = npyv_load_u16(data + vstep * 3);
            npyv_u16 c3 = npyv_load_u16(data_out + vstep * 3);
            
            #line 318
            npyv_u16 abc0 = npyv_muladd_u16(v_scalar, b0, c0);
            
#line 318
            npyv_u16 abc1 = npyv_muladd_u16(v_scalar, b1, c1);
            
#line 318
            npyv_u16 abc2 = npyv_muladd_u16(v_scalar, b2, c2);
            
#line 318
            npyv_u16 abc3 = npyv_muladd_u16(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data, count);
        npyv_u16 b = npyv_load_tillz_u16(data_out, count);
        npyv_store_till_u16(data_out, count, npyv_muladd_u16(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ushort b0 = (data[0]);
        const npy_ushort c0 = (data_out[0]);
        
#line 340
        const npy_ushort b1 = (data[1]);
        const npy_ushort c1 = (data_out[1]);
        
#line 340
        const npy_ushort b2 = (data[2]);
        const npy_ushort c2 = (data_out[2]);
        
#line 340
        const npy_ushort b3 = (data[3]);
        const npy_ushort c3 = (data_out[3]);
        
        #line 346
        const npy_ushort abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ushort abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ushort abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ushort abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ushort b = (*data);
        const npy_ushort c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ushort
}

static void
ushort_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ushort
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u16;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u16 a0 = npyv_loada_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_loada_u16(data1 + vstep * 0);
            npyv_u16 c0 = npyv_loada_u16(data_out + vstep * 0);
            
#line 390
            npyv_u16 a1 = npyv_loada_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_loada_u16(data1 + vstep * 1);
            npyv_u16 c1 = npyv_loada_u16(data_out + vstep * 1);
            
#line 390
            npyv_u16 a2 = npyv_loada_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_loada_u16(data1 + vstep * 2);
            npyv_u16 c2 = npyv_loada_u16(data_out + vstep * 2);
            
#line 390
            npyv_u16 a3 = npyv_loada_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_loada_u16(data1 + vstep * 3);
            npyv_u16 c3 = npyv_loada_u16(data_out + vstep * 3);
            
            #line 397
            npyv_u16 abc0 = npyv_muladd_u16(a0, b0, c0);
            
#line 397
            npyv_u16 abc1 = npyv_muladd_u16(a1, b1, c1);
            
#line 397
            npyv_u16 abc2 = npyv_muladd_u16(a2, b2, c2);
            
#line 397
            npyv_u16 abc3 = npyv_muladd_u16(a3, b3, c3);
            
            #line 402
            npyv_storea_u16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u16 a0 = npyv_load_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_load_u16(data1 + vstep * 0);
            npyv_u16 c0 = npyv_load_u16(data_out + vstep * 0);
            
#line 390
            npyv_u16 a1 = npyv_load_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_load_u16(data1 + vstep * 1);
            npyv_u16 c1 = npyv_load_u16(data_out + vstep * 1);
            
#line 390
            npyv_u16 a2 = npyv_load_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_load_u16(data1 + vstep * 2);
            npyv_u16 c2 = npyv_load_u16(data_out + vstep * 2);
            
#line 390
            npyv_u16 a3 = npyv_load_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_load_u16(data1 + vstep * 3);
            npyv_u16 c3 = npyv_load_u16(data_out + vstep * 3);
            
            #line 397
            npyv_u16 abc0 = npyv_muladd_u16(a0, b0, c0);
            
#line 397
            npyv_u16 abc1 = npyv_muladd_u16(a1, b1, c1);
            
#line 397
            npyv_u16 abc2 = npyv_muladd_u16(a2, b2, c2);
            
#line 397
            npyv_u16 abc3 = npyv_muladd_u16(a3, b3, c3);
            
            #line 402
            npyv_store_u16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data0, count);
        npyv_u16 b = npyv_load_tillz_u16(data1, count);
        npyv_u16 c = npyv_load_tillz_u16(data_out, count);
        npyv_store_till_u16(data_out, count, npyv_muladd_u16(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ushort a0 = (data0[0]);
        const npy_ushort b0 = (data1[0]);
        const npy_ushort c0 = (data_out[0]);
        
#line 420
        const npy_ushort a1 = (data0[1]);
        const npy_ushort b1 = (data1[1]);
        const npy_ushort c1 = (data_out[1]);
        
#line 420
        const npy_ushort a2 = (data0[2]);
        const npy_ushort b2 = (data1[2]);
        const npy_ushort c2 = (data_out[2]);
        
#line 420
        const npy_ushort a3 = (data0[3]);
        const npy_ushort b3 = (data1[3]);
        const npy_ushort c3 = (data_out[3]);
        
        #line 427
        const npy_ushort abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ushort abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ushort abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ushort abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ushort a = (*data0);
        const npy_ushort b = (*data1);
        const npy_ushort c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ushort

}

/* Some extra specializations for the two operand case */
static void
ushort_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort value0 = (*(npy_ushort *)dataptr[0]);
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ushort_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ushort_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort value1 = (*(npy_ushort *)dataptr[1]);
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ushort_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort accum = 0;

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u16;
    npyv_u16 v_accum = npyv_zero_u16();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u16 a0 = npyv_loada_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_loada_u16(data1 + vstep * 0);
            
#line 501
            npyv_u16 a1 = npyv_loada_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_loada_u16(data1 + vstep * 1);
            
#line 501
            npyv_u16 a2 = npyv_loada_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_loada_u16(data1 + vstep * 2);
            
#line 501
            npyv_u16 a3 = npyv_loada_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_loada_u16(data1 + vstep * 3);
            
            npyv_u16 ab3 = npyv_muladd_u16(a3, b3, v_accum);
            npyv_u16 ab2 = npyv_muladd_u16(a2, b2, ab3);
            npyv_u16 ab1 = npyv_muladd_u16(a1, b1, ab2);
                   v_accum = npyv_muladd_u16(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u16 a0 = npyv_load_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_load_u16(data1 + vstep * 0);
            
#line 501
            npyv_u16 a1 = npyv_load_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_load_u16(data1 + vstep * 1);
            
#line 501
            npyv_u16 a2 = npyv_load_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_load_u16(data1 + vstep * 2);
            
#line 501
            npyv_u16 a3 = npyv_load_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_load_u16(data1 + vstep * 3);
            
            npyv_u16 ab3 = npyv_muladd_u16(a3, b3, v_accum);
            npyv_u16 ab2 = npyv_muladd_u16(a2, b2, ab3);
            npyv_u16 ab1 = npyv_muladd_u16(a1, b1, ab2);
                   v_accum = npyv_muladd_u16(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data0, count);
        npyv_u16 b = npyv_load_tillz_u16(data1, count);
        v_accum = npyv_muladd_u16(a, b, v_accum);
    }
    accum = npyv_sum_u16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ushort ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ushort ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ushort ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ushort ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ushort a = (*data0);
        const npy_ushort b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ushort
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort value0 = (*(npy_ushort *)dataptr[0]);
    npy_ushort accum = ushort_sum_of_arr(data1, count);
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort value1 = (*(npy_ushort *)dataptr[1]);
    npy_ushort accum = ushort_sum_of_arr(data0, count);
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
ushort_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data2 = (npy_ushort *)dataptr[2];
    npy_ushort *data_out = (npy_ushort *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
ushort_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        *(npy_ushort *)dataptr[nop] = (temp +
                                           (*(npy_ushort *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ushort);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ushort);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ushort *data = (npy_ushort *)dataptr[0];
    npy_ushort accum = ushort_sum_of_arr(data, count);
    *((npy_ushort *)dataptr[1]) = (accum + (*((npy_ushort *)dataptr[1])));
#else
    npy_ushort accum_re = 0, accum_im = 0;
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ushort re01 = data0[0] + data0[2];
        const npy_ushort re23 = data0[4] + data0[6];
        const npy_ushort im13 = data0[1] + data0[3];
        const npy_ushort im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ushort *)dataptr[1])[0] += accum_re;
    ((npy_ushort *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
ushort_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ushort accum_re = 0, accum_im = 0;
#else
    npy_ushort accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_ushort *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_ushort *)data0) *
                 (*(npy_ushort *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_ushort *)data0) *
                 (*(npy_ushort *)data1) *
                 (*(npy_ushort *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_ushort *)data0)[0];
        accum_im += ((npy_ushort *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_ushort *)dataptr[3])[0] += accum_re;
    ((npy_ushort *)dataptr[3])[1] += accum_im;
#  else
    ((npy_ushort *)dataptr[nop])[0] += accum_re;
    ((npy_ushort *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_ushort *)dataptr[3]) = (accum +
                                    (*((npy_ushort *)dataptr[3])));
#  else
    *((npy_ushort *)dataptr[nop]) = (accum +
                                    (*((npy_ushort *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ushort_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) *
                                         (*(npy_ushort *)data1) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_ushort *)data_out = ((*(npy_ushort *)data0) *
                                         (*(npy_ushort *)data1) *
                                         (*(npy_ushort *)data2) +
                                         (*(npy_ushort *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        *(npy_ushort *)dataptr[nop] = (temp +
                                           (*(npy_ushort *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_ushort *)data_out)[0] = ((npy_ushort *)data0)[0] +
                                         ((npy_ushort *)data_out)[0];
        ((npy_ushort *)data_out)[1] = ((npy_ushort *)data0)[1] +
                                         ((npy_ushort *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
ushort_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data_out = (npy_ushort *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ushort *)data_out + 2*6)[0] =
                                    ((npy_ushort *)data0 + 2*6)[0] +
                                    ((npy_ushort *)data_out + 2*6)[0];
            ((npy_ushort *)data_out + 2*6)[1] =
                                    ((npy_ushort *)data0 + 2*6)[1] +
                                    ((npy_ushort *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ushort *)data_out + 2*5)[0] =
                                    ((npy_ushort *)data0 + 2*5)[0] +
                                    ((npy_ushort *)data_out + 2*5)[0];
            ((npy_ushort *)data_out + 2*5)[1] =
                                    ((npy_ushort *)data0 + 2*5)[1] +
                                    ((npy_ushort *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ushort *)data_out + 2*4)[0] =
                                    ((npy_ushort *)data0 + 2*4)[0] +
                                    ((npy_ushort *)data_out + 2*4)[0];
            ((npy_ushort *)data_out + 2*4)[1] =
                                    ((npy_ushort *)data0 + 2*4)[1] +
                                    ((npy_ushort *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ushort *)data_out + 2*3)[0] =
                                    ((npy_ushort *)data0 + 2*3)[0] +
                                    ((npy_ushort *)data_out + 2*3)[0];
            ((npy_ushort *)data_out + 2*3)[1] =
                                    ((npy_ushort *)data0 + 2*3)[1] +
                                    ((npy_ushort *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ushort *)data_out + 2*2)[0] =
                                    ((npy_ushort *)data0 + 2*2)[0] +
                                    ((npy_ushort *)data_out + 2*2)[0];
            ((npy_ushort *)data_out + 2*2)[1] =
                                    ((npy_ushort *)data0 + 2*2)[1] +
                                    ((npy_ushort *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ushort *)data_out + 2*1)[0] =
                                    ((npy_ushort *)data0 + 2*1)[0] +
                                    ((npy_ushort *)data_out + 2*1)[0];
            ((npy_ushort *)data_out + 2*1)[1] =
                                    ((npy_ushort *)data0 + 2*1)[1] +
                                    ((npy_ushort *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ushort *)data_out + 2*0)[0] =
                                    ((npy_ushort *)data0 + 2*0)[0] +
                                    ((npy_ushort *)data_out + 2*0)[0];
            ((npy_ushort *)data_out + 2*0)[1] =
                                    ((npy_ushort *)data0 + 2*0)[1] +
                                    ((npy_ushort *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ushort *)data_out + 2*0)[0] =
                                ((npy_ushort *)data0 + 2*0)[0] +
                                ((npy_ushort *)data_out + 2*0)[0];
        ((npy_ushort *)data_out + 2*0)[1] =
                                ((npy_ushort *)data0 + 2*0)[1] +
                                ((npy_ushort *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ushort *)data_out + 2*1)[0] =
                                ((npy_ushort *)data0 + 2*1)[0] +
                                ((npy_ushort *)data_out + 2*1)[0];
        ((npy_ushort *)data_out + 2*1)[1] =
                                ((npy_ushort *)data0 + 2*1)[1] +
                                ((npy_ushort *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ushort *)data_out + 2*2)[0] =
                                ((npy_ushort *)data0 + 2*2)[0] +
                                ((npy_ushort *)data_out + 2*2)[0];
        ((npy_ushort *)data_out + 2*2)[1] =
                                ((npy_ushort *)data0 + 2*2)[1] +
                                ((npy_ushort *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ushort *)data_out + 2*3)[0] =
                                ((npy_ushort *)data0 + 2*3)[0] +
                                ((npy_ushort *)data_out + 2*3)[0];
        ((npy_ushort *)data_out + 2*3)[1] =
                                ((npy_ushort *)data0 + 2*3)[1] +
                                ((npy_ushort *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ushort *)data_out + 2*4)[0] =
                                ((npy_ushort *)data0 + 2*4)[0] +
                                ((npy_ushort *)data_out + 2*4)[0];
        ((npy_ushort *)data_out + 2*4)[1] =
                                ((npy_ushort *)data0 + 2*4)[1] +
                                ((npy_ushort *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ushort *)data_out + 2*5)[0] =
                                ((npy_ushort *)data0 + 2*5)[0] +
                                ((npy_ushort *)data_out + 2*5)[0];
        ((npy_ushort *)data_out + 2*5)[1] =
                                ((npy_ushort *)data0 + 2*5)[1] +
                                ((npy_ushort *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ushort *)data_out + 2*6)[0] =
                                ((npy_ushort *)data0 + 2*6)[0] +
                                ((npy_ushort *)data_out + 2*6)[0];
        ((npy_ushort *)data_out + 2*6)[1] =
                                ((npy_ushort *)data0 + 2*6)[1] +
                                ((npy_ushort *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ushort *)data_out + 2*7)[0] =
                                ((npy_ushort *)data0 + 2*7)[0] +
                                ((npy_ushort *)data_out + 2*7)[0];
        ((npy_ushort *)data_out + 2*7)[1] =
                                ((npy_ushort *)data0 + 2*7)[1] +
                                ((npy_ushort *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ushort_sum_of_products_muladd(npy_ushort *data, npy_ushort *data_out, npy_ushort scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u16;
    const npyv_u16 v_scalar = npyv_setall_u16(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u16 b0 = npyv_loada_u16(data + vstep * 0);
            npyv_u16 c0 = npyv_loada_u16(data_out + vstep * 0);
            
#line 312
            npyv_u16 b1 = npyv_loada_u16(data + vstep * 1);
            npyv_u16 c1 = npyv_loada_u16(data_out + vstep * 1);
            
#line 312
            npyv_u16 b2 = npyv_loada_u16(data + vstep * 2);
            npyv_u16 c2 = npyv_loada_u16(data_out + vstep * 2);
            
#line 312
            npyv_u16 b3 = npyv_loada_u16(data + vstep * 3);
            npyv_u16 c3 = npyv_loada_u16(data_out + vstep * 3);
            
            #line 318
            npyv_u16 abc0 = npyv_muladd_u16(v_scalar, b0, c0);
            
#line 318
            npyv_u16 abc1 = npyv_muladd_u16(v_scalar, b1, c1);
            
#line 318
            npyv_u16 abc2 = npyv_muladd_u16(v_scalar, b2, c2);
            
#line 318
            npyv_u16 abc3 = npyv_muladd_u16(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u16 b0 = npyv_load_u16(data + vstep * 0);
            npyv_u16 c0 = npyv_load_u16(data_out + vstep * 0);
            
#line 312
            npyv_u16 b1 = npyv_load_u16(data + vstep * 1);
            npyv_u16 c1 = npyv_load_u16(data_out + vstep * 1);
            
#line 312
            npyv_u16 b2 = npyv_load_u16(data + vstep * 2);
            npyv_u16 c2 = npyv_load_u16(data_out + vstep * 2);
            
#line 312
            npyv_u16 b3 = npyv_load_u16(data + vstep * 3);
            npyv_u16 c3 = npyv_load_u16(data_out + vstep * 3);
            
            #line 318
            npyv_u16 abc0 = npyv_muladd_u16(v_scalar, b0, c0);
            
#line 318
            npyv_u16 abc1 = npyv_muladd_u16(v_scalar, b1, c1);
            
#line 318
            npyv_u16 abc2 = npyv_muladd_u16(v_scalar, b2, c2);
            
#line 318
            npyv_u16 abc3 = npyv_muladd_u16(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u16(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u16(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u16(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data, count);
        npyv_u16 b = npyv_load_tillz_u16(data_out, count);
        npyv_store_till_u16(data_out, count, npyv_muladd_u16(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ushort b0 = (data[0]);
        const npy_ushort c0 = (data_out[0]);
        
#line 340
        const npy_ushort b1 = (data[1]);
        const npy_ushort c1 = (data_out[1]);
        
#line 340
        const npy_ushort b2 = (data[2]);
        const npy_ushort c2 = (data_out[2]);
        
#line 340
        const npy_ushort b3 = (data[3]);
        const npy_ushort c3 = (data_out[3]);
        
        #line 346
        const npy_ushort abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ushort abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ushort abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ushort abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ushort b = (*data);
        const npy_ushort c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ushort
}

static void
ushort_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ushort
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u16;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u16 a0 = npyv_loada_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_loada_u16(data1 + vstep * 0);
            npyv_u16 c0 = npyv_loada_u16(data_out + vstep * 0);
            
#line 390
            npyv_u16 a1 = npyv_loada_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_loada_u16(data1 + vstep * 1);
            npyv_u16 c1 = npyv_loada_u16(data_out + vstep * 1);
            
#line 390
            npyv_u16 a2 = npyv_loada_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_loada_u16(data1 + vstep * 2);
            npyv_u16 c2 = npyv_loada_u16(data_out + vstep * 2);
            
#line 390
            npyv_u16 a3 = npyv_loada_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_loada_u16(data1 + vstep * 3);
            npyv_u16 c3 = npyv_loada_u16(data_out + vstep * 3);
            
            #line 397
            npyv_u16 abc0 = npyv_muladd_u16(a0, b0, c0);
            
#line 397
            npyv_u16 abc1 = npyv_muladd_u16(a1, b1, c1);
            
#line 397
            npyv_u16 abc2 = npyv_muladd_u16(a2, b2, c2);
            
#line 397
            npyv_u16 abc3 = npyv_muladd_u16(a3, b3, c3);
            
            #line 402
            npyv_storea_u16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u16 a0 = npyv_load_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_load_u16(data1 + vstep * 0);
            npyv_u16 c0 = npyv_load_u16(data_out + vstep * 0);
            
#line 390
            npyv_u16 a1 = npyv_load_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_load_u16(data1 + vstep * 1);
            npyv_u16 c1 = npyv_load_u16(data_out + vstep * 1);
            
#line 390
            npyv_u16 a2 = npyv_load_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_load_u16(data1 + vstep * 2);
            npyv_u16 c2 = npyv_load_u16(data_out + vstep * 2);
            
#line 390
            npyv_u16 a3 = npyv_load_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_load_u16(data1 + vstep * 3);
            npyv_u16 c3 = npyv_load_u16(data_out + vstep * 3);
            
            #line 397
            npyv_u16 abc0 = npyv_muladd_u16(a0, b0, c0);
            
#line 397
            npyv_u16 abc1 = npyv_muladd_u16(a1, b1, c1);
            
#line 397
            npyv_u16 abc2 = npyv_muladd_u16(a2, b2, c2);
            
#line 397
            npyv_u16 abc3 = npyv_muladd_u16(a3, b3, c3);
            
            #line 402
            npyv_store_u16(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u16(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u16(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u16(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data0, count);
        npyv_u16 b = npyv_load_tillz_u16(data1, count);
        npyv_u16 c = npyv_load_tillz_u16(data_out, count);
        npyv_store_till_u16(data_out, count, npyv_muladd_u16(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ushort a0 = (data0[0]);
        const npy_ushort b0 = (data1[0]);
        const npy_ushort c0 = (data_out[0]);
        
#line 420
        const npy_ushort a1 = (data0[1]);
        const npy_ushort b1 = (data1[1]);
        const npy_ushort c1 = (data_out[1]);
        
#line 420
        const npy_ushort a2 = (data0[2]);
        const npy_ushort b2 = (data1[2]);
        const npy_ushort c2 = (data_out[2]);
        
#line 420
        const npy_ushort a3 = (data0[3]);
        const npy_ushort b3 = (data1[3]);
        const npy_ushort c3 = (data_out[3]);
        
        #line 427
        const npy_ushort abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ushort abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ushort abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ushort abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ushort a = (*data0);
        const npy_ushort b = (*data1);
        const npy_ushort c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ushort

}

/* Some extra specializations for the two operand case */
static void
ushort_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort value0 = (*(npy_ushort *)dataptr[0]);
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ushort_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ushort_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort value1 = (*(npy_ushort *)dataptr[1]);
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data_out = (npy_ushort *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ushort_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort accum = 0;

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ushort
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u16;
    npyv_u16 v_accum = npyv_zero_u16();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u16 a0 = npyv_loada_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_loada_u16(data1 + vstep * 0);
            
#line 501
            npyv_u16 a1 = npyv_loada_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_loada_u16(data1 + vstep * 1);
            
#line 501
            npyv_u16 a2 = npyv_loada_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_loada_u16(data1 + vstep * 2);
            
#line 501
            npyv_u16 a3 = npyv_loada_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_loada_u16(data1 + vstep * 3);
            
            npyv_u16 ab3 = npyv_muladd_u16(a3, b3, v_accum);
            npyv_u16 ab2 = npyv_muladd_u16(a2, b2, ab3);
            npyv_u16 ab1 = npyv_muladd_u16(a1, b1, ab2);
                   v_accum = npyv_muladd_u16(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u16 a0 = npyv_load_u16(data0 + vstep * 0);
            npyv_u16 b0 = npyv_load_u16(data1 + vstep * 0);
            
#line 501
            npyv_u16 a1 = npyv_load_u16(data0 + vstep * 1);
            npyv_u16 b1 = npyv_load_u16(data1 + vstep * 1);
            
#line 501
            npyv_u16 a2 = npyv_load_u16(data0 + vstep * 2);
            npyv_u16 b2 = npyv_load_u16(data1 + vstep * 2);
            
#line 501
            npyv_u16 a3 = npyv_load_u16(data0 + vstep * 3);
            npyv_u16 b3 = npyv_load_u16(data1 + vstep * 3);
            
            npyv_u16 ab3 = npyv_muladd_u16(a3, b3, v_accum);
            npyv_u16 ab2 = npyv_muladd_u16(a2, b2, ab3);
            npyv_u16 ab1 = npyv_muladd_u16(a1, b1, ab2);
                   v_accum = npyv_muladd_u16(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u16 a = npyv_load_tillz_u16(data0, count);
        npyv_u16 b = npyv_load_tillz_u16(data1, count);
        v_accum = npyv_muladd_u16(a, b, v_accum);
    }
    accum = npyv_sum_u16(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ushort ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ushort ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ushort ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ushort ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ushort a = (*data0);
        const npy_ushort b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ushort
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort value0 = (*(npy_ushort *)dataptr[0]);
    npy_ushort accum = ushort_sum_of_arr(data1, count);
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort value1 = (*(npy_ushort *)dataptr[1]);
    npy_ushort accum = ushort_sum_of_arr(data0, count);
    *(npy_ushort *)dataptr[2] = ((*(npy_ushort *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
ushort_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
    npy_ushort *data1 = (npy_ushort *)dataptr[1];
    npy_ushort *data2 = (npy_ushort *)dataptr[2];
    npy_ushort *data_out = (npy_ushort *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
ushort_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        *(npy_ushort *)dataptr[nop] = (temp +
                                           (*(npy_ushort *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ushort);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ushort *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ushort *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ushort);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
ushort_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ushort *data = (npy_ushort *)dataptr[0];
    npy_ushort accum = ushort_sum_of_arr(data, count);
    *((npy_ushort *)dataptr[1]) = (accum + (*((npy_ushort *)dataptr[1])));
#else
    npy_ushort accum_re = 0, accum_im = 0;
    npy_ushort *data0 = (npy_ushort *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ushort re01 = data0[0] + data0[2];
        const npy_ushort re23 = data0[4] + data0[6];
        const npy_ushort im13 = data0[1] + data0[3];
        const npy_ushort im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ushort *)dataptr[1])[0] += accum_re;
    ((npy_ushort *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
ushort_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ushort accum_re = 0, accum_im = 0;
#else
    npy_ushort accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ushort_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_ushort *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_ushort *)data0) *
                 (*(npy_ushort *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_ushort *)data0) *
                 (*(npy_ushort *)data1) *
                 (*(npy_ushort *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ushort temp = (*(npy_ushort *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ushort *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_ushort *)data0)[0];
        accum_im += ((npy_ushort *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ushort re, im, tmp;
        int i;
        re = ((npy_ushort *)dataptr[0])[0];
        im = ((npy_ushort *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ushort *)dataptr[i])[0] -
                  im * ((npy_ushort *)dataptr[i])[1];
            im = re * ((npy_ushort *)dataptr[i])[1] +
                 im * ((npy_ushort *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_ushort *)dataptr[1000])[0] += accum_re;
    ((npy_ushort *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_ushort *)dataptr[nop])[0] += accum_re;
    ((npy_ushort *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_ushort *)dataptr[1000]) = (accum +
                                    (*((npy_ushort *)dataptr[1000])));
#  else
    *((npy_ushort *)dataptr[nop]) = (accum +
                                    (*((npy_ushort *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_uint uint_sum_of_arr(npy_uint *data, npy_intp count)
{
    npy_uint accum = 0;
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_u32;
    npyv_u32 v_accum = npyv_zero_u32();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_u32 a0 = npyv_loada_u32(data + vstep * 0);
            
#line 96
            npyv_u32 a1 = npyv_loada_u32(data + vstep * 1);
            
#line 96
            npyv_u32 a2 = npyv_loada_u32(data + vstep * 2);
            
#line 96
            npyv_u32 a3 = npyv_loada_u32(data + vstep * 3);
            
            npyv_u32 a01   = npyv_add_u32(a0, a1);
            npyv_u32 a23   = npyv_add_u32(a2, a3);
            npyv_u32 a0123 = npyv_add_u32(a01, a23);
                     v_accum = npyv_add_u32(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_u32 a0 = npyv_load_u32(data + vstep * 0);
            
#line 96
            npyv_u32 a1 = npyv_load_u32(data + vstep * 1);
            
#line 96
            npyv_u32 a2 = npyv_load_u32(data + vstep * 2);
            
#line 96
            npyv_u32 a3 = npyv_load_u32(data + vstep * 3);
            
            npyv_u32 a01   = npyv_add_u32(a0, a1);
            npyv_u32 a23   = npyv_add_u32(a2, a3);
            npyv_u32 a0123 = npyv_add_u32(a01, a23);
                     v_accum = npyv_add_u32(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data, count);
        v_accum = npyv_add_u32(a, v_accum);
    }
    accum = npyv_sum_u32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_uint a01 = (*data) + (data[1]);
        const npy_uint a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_uint
    return accum;
}
#endif

#line 131
static void
uint_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_uint *)data_out = ((*(npy_uint *)data0) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_uint *)data_out = ((*(npy_uint *)data0) *
                                         (*(npy_uint *)data1) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_uint *)data_out = ((*(npy_uint *)data0) *
                                         (*(npy_uint *)data1) *
                                         (*(npy_uint *)data2) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        *(npy_uint *)dataptr[nop] = (temp +
                                           (*(npy_uint *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_uint *)data_out)[0] = ((npy_uint *)data0)[0] +
                                         ((npy_uint *)data_out)[0];
        ((npy_uint *)data_out)[1] = ((npy_uint *)data0)[1] +
                                         ((npy_uint *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_uint *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[0];
        ((npy_uint *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
uint_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data_out = (npy_uint *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_uint *)data_out + 2*6)[0] =
                                    ((npy_uint *)data0 + 2*6)[0] +
                                    ((npy_uint *)data_out + 2*6)[0];
            ((npy_uint *)data_out + 2*6)[1] =
                                    ((npy_uint *)data0 + 2*6)[1] +
                                    ((npy_uint *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_uint *)data_out + 2*5)[0] =
                                    ((npy_uint *)data0 + 2*5)[0] +
                                    ((npy_uint *)data_out + 2*5)[0];
            ((npy_uint *)data_out + 2*5)[1] =
                                    ((npy_uint *)data0 + 2*5)[1] +
                                    ((npy_uint *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_uint *)data_out + 2*4)[0] =
                                    ((npy_uint *)data0 + 2*4)[0] +
                                    ((npy_uint *)data_out + 2*4)[0];
            ((npy_uint *)data_out + 2*4)[1] =
                                    ((npy_uint *)data0 + 2*4)[1] +
                                    ((npy_uint *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_uint *)data_out + 2*3)[0] =
                                    ((npy_uint *)data0 + 2*3)[0] +
                                    ((npy_uint *)data_out + 2*3)[0];
            ((npy_uint *)data_out + 2*3)[1] =
                                    ((npy_uint *)data0 + 2*3)[1] +
                                    ((npy_uint *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_uint *)data_out + 2*2)[0] =
                                    ((npy_uint *)data0 + 2*2)[0] +
                                    ((npy_uint *)data_out + 2*2)[0];
            ((npy_uint *)data_out + 2*2)[1] =
                                    ((npy_uint *)data0 + 2*2)[1] +
                                    ((npy_uint *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_uint *)data_out + 2*1)[0] =
                                    ((npy_uint *)data0 + 2*1)[0] +
                                    ((npy_uint *)data_out + 2*1)[0];
            ((npy_uint *)data_out + 2*1)[1] =
                                    ((npy_uint *)data0 + 2*1)[1] +
                                    ((npy_uint *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_uint *)data_out + 2*0)[0] =
                                    ((npy_uint *)data0 + 2*0)[0] +
                                    ((npy_uint *)data_out + 2*0)[0];
            ((npy_uint *)data_out + 2*0)[1] =
                                    ((npy_uint *)data0 + 2*0)[1] +
                                    ((npy_uint *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_uint *)data_out + 2*0)[0] =
                                ((npy_uint *)data0 + 2*0)[0] +
                                ((npy_uint *)data_out + 2*0)[0];
        ((npy_uint *)data_out + 2*0)[1] =
                                ((npy_uint *)data0 + 2*0)[1] +
                                ((npy_uint *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_uint *)data_out + 2*1)[0] =
                                ((npy_uint *)data0 + 2*1)[0] +
                                ((npy_uint *)data_out + 2*1)[0];
        ((npy_uint *)data_out + 2*1)[1] =
                                ((npy_uint *)data0 + 2*1)[1] +
                                ((npy_uint *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_uint *)data_out + 2*2)[0] =
                                ((npy_uint *)data0 + 2*2)[0] +
                                ((npy_uint *)data_out + 2*2)[0];
        ((npy_uint *)data_out + 2*2)[1] =
                                ((npy_uint *)data0 + 2*2)[1] +
                                ((npy_uint *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_uint *)data_out + 2*3)[0] =
                                ((npy_uint *)data0 + 2*3)[0] +
                                ((npy_uint *)data_out + 2*3)[0];
        ((npy_uint *)data_out + 2*3)[1] =
                                ((npy_uint *)data0 + 2*3)[1] +
                                ((npy_uint *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_uint *)data_out + 2*4)[0] =
                                ((npy_uint *)data0 + 2*4)[0] +
                                ((npy_uint *)data_out + 2*4)[0];
        ((npy_uint *)data_out + 2*4)[1] =
                                ((npy_uint *)data0 + 2*4)[1] +
                                ((npy_uint *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_uint *)data_out + 2*5)[0] =
                                ((npy_uint *)data0 + 2*5)[0] +
                                ((npy_uint *)data_out + 2*5)[0];
        ((npy_uint *)data_out + 2*5)[1] =
                                ((npy_uint *)data0 + 2*5)[1] +
                                ((npy_uint *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_uint *)data_out + 2*6)[0] =
                                ((npy_uint *)data0 + 2*6)[0] +
                                ((npy_uint *)data_out + 2*6)[0];
        ((npy_uint *)data_out + 2*6)[1] =
                                ((npy_uint *)data0 + 2*6)[1] +
                                ((npy_uint *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_uint *)data_out + 2*7)[0] =
                                ((npy_uint *)data0 + 2*7)[0] +
                                ((npy_uint *)data_out + 2*7)[0];
        ((npy_uint *)data_out + 2*7)[1] =
                                ((npy_uint *)data0 + 2*7)[1] +
                                ((npy_uint *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
uint_sum_of_products_muladd(npy_uint *data, npy_uint *data_out, npy_uint scalar, npy_intp count)
{
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u32;
    const npyv_u32 v_scalar = npyv_setall_u32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u32 b0 = npyv_loada_u32(data + vstep * 0);
            npyv_u32 c0 = npyv_loada_u32(data_out + vstep * 0);
            
#line 312
            npyv_u32 b1 = npyv_loada_u32(data + vstep * 1);
            npyv_u32 c1 = npyv_loada_u32(data_out + vstep * 1);
            
#line 312
            npyv_u32 b2 = npyv_loada_u32(data + vstep * 2);
            npyv_u32 c2 = npyv_loada_u32(data_out + vstep * 2);
            
#line 312
            npyv_u32 b3 = npyv_loada_u32(data + vstep * 3);
            npyv_u32 c3 = npyv_loada_u32(data_out + vstep * 3);
            
            #line 318
            npyv_u32 abc0 = npyv_muladd_u32(v_scalar, b0, c0);
            
#line 318
            npyv_u32 abc1 = npyv_muladd_u32(v_scalar, b1, c1);
            
#line 318
            npyv_u32 abc2 = npyv_muladd_u32(v_scalar, b2, c2);
            
#line 318
            npyv_u32 abc3 = npyv_muladd_u32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u32 b0 = npyv_load_u32(data + vstep * 0);
            npyv_u32 c0 = npyv_load_u32(data_out + vstep * 0);
            
#line 312
            npyv_u32 b1 = npyv_load_u32(data + vstep * 1);
            npyv_u32 c1 = npyv_load_u32(data_out + vstep * 1);
            
#line 312
            npyv_u32 b2 = npyv_load_u32(data + vstep * 2);
            npyv_u32 c2 = npyv_load_u32(data_out + vstep * 2);
            
#line 312
            npyv_u32 b3 = npyv_load_u32(data + vstep * 3);
            npyv_u32 c3 = npyv_load_u32(data_out + vstep * 3);
            
            #line 318
            npyv_u32 abc0 = npyv_muladd_u32(v_scalar, b0, c0);
            
#line 318
            npyv_u32 abc1 = npyv_muladd_u32(v_scalar, b1, c1);
            
#line 318
            npyv_u32 abc2 = npyv_muladd_u32(v_scalar, b2, c2);
            
#line 318
            npyv_u32 abc3 = npyv_muladd_u32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data, count);
        npyv_u32 b = npyv_load_tillz_u32(data_out, count);
        npyv_store_till_u32(data_out, count, npyv_muladd_u32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_uint b0 = (data[0]);
        const npy_uint c0 = (data_out[0]);
        
#line 340
        const npy_uint b1 = (data[1]);
        const npy_uint c1 = (data_out[1]);
        
#line 340
        const npy_uint b2 = (data[2]);
        const npy_uint c2 = (data_out[2]);
        
#line 340
        const npy_uint b3 = (data[3]);
        const npy_uint c3 = (data_out[3]);
        
        #line 346
        const npy_uint abc0 = scalar * b0 + c0;
        
#line 346
        const npy_uint abc1 = scalar * b1 + c1;
        
#line 346
        const npy_uint abc2 = scalar * b2 + c2;
        
#line 346
        const npy_uint abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_uint b = (*data);
        const npy_uint c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_uint
}

static void
uint_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data_out = (npy_uint *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_uint
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u32 a0 = npyv_loada_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_loada_u32(data1 + vstep * 0);
            npyv_u32 c0 = npyv_loada_u32(data_out + vstep * 0);
            
#line 390
            npyv_u32 a1 = npyv_loada_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_loada_u32(data1 + vstep * 1);
            npyv_u32 c1 = npyv_loada_u32(data_out + vstep * 1);
            
#line 390
            npyv_u32 a2 = npyv_loada_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_loada_u32(data1 + vstep * 2);
            npyv_u32 c2 = npyv_loada_u32(data_out + vstep * 2);
            
#line 390
            npyv_u32 a3 = npyv_loada_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_loada_u32(data1 + vstep * 3);
            npyv_u32 c3 = npyv_loada_u32(data_out + vstep * 3);
            
            #line 397
            npyv_u32 abc0 = npyv_muladd_u32(a0, b0, c0);
            
#line 397
            npyv_u32 abc1 = npyv_muladd_u32(a1, b1, c1);
            
#line 397
            npyv_u32 abc2 = npyv_muladd_u32(a2, b2, c2);
            
#line 397
            npyv_u32 abc3 = npyv_muladd_u32(a3, b3, c3);
            
            #line 402
            npyv_storea_u32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u32 a0 = npyv_load_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_load_u32(data1 + vstep * 0);
            npyv_u32 c0 = npyv_load_u32(data_out + vstep * 0);
            
#line 390
            npyv_u32 a1 = npyv_load_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_load_u32(data1 + vstep * 1);
            npyv_u32 c1 = npyv_load_u32(data_out + vstep * 1);
            
#line 390
            npyv_u32 a2 = npyv_load_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_load_u32(data1 + vstep * 2);
            npyv_u32 c2 = npyv_load_u32(data_out + vstep * 2);
            
#line 390
            npyv_u32 a3 = npyv_load_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_load_u32(data1 + vstep * 3);
            npyv_u32 c3 = npyv_load_u32(data_out + vstep * 3);
            
            #line 397
            npyv_u32 abc0 = npyv_muladd_u32(a0, b0, c0);
            
#line 397
            npyv_u32 abc1 = npyv_muladd_u32(a1, b1, c1);
            
#line 397
            npyv_u32 abc2 = npyv_muladd_u32(a2, b2, c2);
            
#line 397
            npyv_u32 abc3 = npyv_muladd_u32(a3, b3, c3);
            
            #line 402
            npyv_store_u32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data0, count);
        npyv_u32 b = npyv_load_tillz_u32(data1, count);
        npyv_u32 c = npyv_load_tillz_u32(data_out, count);
        npyv_store_till_u32(data_out, count, npyv_muladd_u32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_uint a0 = (data0[0]);
        const npy_uint b0 = (data1[0]);
        const npy_uint c0 = (data_out[0]);
        
#line 420
        const npy_uint a1 = (data0[1]);
        const npy_uint b1 = (data1[1]);
        const npy_uint c1 = (data_out[1]);
        
#line 420
        const npy_uint a2 = (data0[2]);
        const npy_uint b2 = (data1[2]);
        const npy_uint c2 = (data_out[2]);
        
#line 420
        const npy_uint a3 = (data0[3]);
        const npy_uint b3 = (data1[3]);
        const npy_uint c3 = (data_out[3]);
        
        #line 427
        const npy_uint abc0 = a0 * b0 + c0;
        
#line 427
        const npy_uint abc1 = a1 * b1 + c1;
        
#line 427
        const npy_uint abc2 = a2 * b2 + c2;
        
#line 427
        const npy_uint abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_uint a = (*data0);
        const npy_uint b = (*data1);
        const npy_uint c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_uint

}

/* Some extra specializations for the two operand case */
static void
uint_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint value0 = (*(npy_uint *)dataptr[0]);
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data_out = (npy_uint *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    uint_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
uint_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint value1 = (*(npy_uint *)dataptr[1]);
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data_out = (npy_uint *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    uint_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint accum = 0;

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u32;
    npyv_u32 v_accum = npyv_zero_u32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u32 a0 = npyv_loada_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_loada_u32(data1 + vstep * 0);
            
#line 501
            npyv_u32 a1 = npyv_loada_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_loada_u32(data1 + vstep * 1);
            
#line 501
            npyv_u32 a2 = npyv_loada_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_loada_u32(data1 + vstep * 2);
            
#line 501
            npyv_u32 a3 = npyv_loada_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_loada_u32(data1 + vstep * 3);
            
            npyv_u32 ab3 = npyv_muladd_u32(a3, b3, v_accum);
            npyv_u32 ab2 = npyv_muladd_u32(a2, b2, ab3);
            npyv_u32 ab1 = npyv_muladd_u32(a1, b1, ab2);
                   v_accum = npyv_muladd_u32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u32 a0 = npyv_load_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_load_u32(data1 + vstep * 0);
            
#line 501
            npyv_u32 a1 = npyv_load_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_load_u32(data1 + vstep * 1);
            
#line 501
            npyv_u32 a2 = npyv_load_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_load_u32(data1 + vstep * 2);
            
#line 501
            npyv_u32 a3 = npyv_load_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_load_u32(data1 + vstep * 3);
            
            npyv_u32 ab3 = npyv_muladd_u32(a3, b3, v_accum);
            npyv_u32 ab2 = npyv_muladd_u32(a2, b2, ab3);
            npyv_u32 ab1 = npyv_muladd_u32(a1, b1, ab2);
                   v_accum = npyv_muladd_u32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data0, count);
        npyv_u32 b = npyv_load_tillz_u32(data1, count);
        v_accum = npyv_muladd_u32(a, b, v_accum);
    }
    accum = npyv_sum_u32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_uint ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_uint ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_uint ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_uint ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_uint a = (*data0);
        const npy_uint b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_uint
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint value0 = (*(npy_uint *)dataptr[0]);
    npy_uint accum = uint_sum_of_arr(data1, count);
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint value1 = (*(npy_uint *)dataptr[1]);
    npy_uint accum = uint_sum_of_arr(data0, count);
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
uint_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data2 = (npy_uint *)dataptr[2];
    npy_uint *data_out = (npy_uint *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
uint_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        *(npy_uint *)dataptr[nop] = (temp +
                                           (*(npy_uint *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_uint);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_uint *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[0];
        ((npy_uint *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_uint);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_uint *data = (npy_uint *)dataptr[0];
    npy_uint accum = uint_sum_of_arr(data, count);
    *((npy_uint *)dataptr[1]) = (accum + (*((npy_uint *)dataptr[1])));
#else
    npy_uint accum_re = 0, accum_im = 0;
    npy_uint *data0 = (npy_uint *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_uint re01 = data0[0] + data0[2];
        const npy_uint re23 = data0[4] + data0[6];
        const npy_uint im13 = data0[1] + data0[3];
        const npy_uint im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_uint *)dataptr[1])[0] += accum_re;
    ((npy_uint *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
uint_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_uint accum_re = 0, accum_im = 0;
#else
    npy_uint accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_uint *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_uint *)data0) *
                 (*(npy_uint *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_uint *)data0) *
                 (*(npy_uint *)data1) *
                 (*(npy_uint *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_uint *)data0)[0];
        accum_im += ((npy_uint *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_uint *)dataptr[1])[0] += accum_re;
    ((npy_uint *)dataptr[1])[1] += accum_im;
#  else
    ((npy_uint *)dataptr[nop])[0] += accum_re;
    ((npy_uint *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_uint *)dataptr[1]) = (accum +
                                    (*((npy_uint *)dataptr[1])));
#  else
    *((npy_uint *)dataptr[nop]) = (accum +
                                    (*((npy_uint *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
uint_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_uint *)data_out = ((*(npy_uint *)data0) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_uint *)data_out = ((*(npy_uint *)data0) *
                                         (*(npy_uint *)data1) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_uint *)data_out = ((*(npy_uint *)data0) *
                                         (*(npy_uint *)data1) *
                                         (*(npy_uint *)data2) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        *(npy_uint *)dataptr[nop] = (temp +
                                           (*(npy_uint *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_uint *)data_out)[0] = ((npy_uint *)data0)[0] +
                                         ((npy_uint *)data_out)[0];
        ((npy_uint *)data_out)[1] = ((npy_uint *)data0)[1] +
                                         ((npy_uint *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_uint *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[0];
        ((npy_uint *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
uint_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data_out = (npy_uint *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_uint *)data_out + 2*6)[0] =
                                    ((npy_uint *)data0 + 2*6)[0] +
                                    ((npy_uint *)data_out + 2*6)[0];
            ((npy_uint *)data_out + 2*6)[1] =
                                    ((npy_uint *)data0 + 2*6)[1] +
                                    ((npy_uint *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_uint *)data_out + 2*5)[0] =
                                    ((npy_uint *)data0 + 2*5)[0] +
                                    ((npy_uint *)data_out + 2*5)[0];
            ((npy_uint *)data_out + 2*5)[1] =
                                    ((npy_uint *)data0 + 2*5)[1] +
                                    ((npy_uint *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_uint *)data_out + 2*4)[0] =
                                    ((npy_uint *)data0 + 2*4)[0] +
                                    ((npy_uint *)data_out + 2*4)[0];
            ((npy_uint *)data_out + 2*4)[1] =
                                    ((npy_uint *)data0 + 2*4)[1] +
                                    ((npy_uint *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_uint *)data_out + 2*3)[0] =
                                    ((npy_uint *)data0 + 2*3)[0] +
                                    ((npy_uint *)data_out + 2*3)[0];
            ((npy_uint *)data_out + 2*3)[1] =
                                    ((npy_uint *)data0 + 2*3)[1] +
                                    ((npy_uint *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_uint *)data_out + 2*2)[0] =
                                    ((npy_uint *)data0 + 2*2)[0] +
                                    ((npy_uint *)data_out + 2*2)[0];
            ((npy_uint *)data_out + 2*2)[1] =
                                    ((npy_uint *)data0 + 2*2)[1] +
                                    ((npy_uint *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_uint *)data_out + 2*1)[0] =
                                    ((npy_uint *)data0 + 2*1)[0] +
                                    ((npy_uint *)data_out + 2*1)[0];
            ((npy_uint *)data_out + 2*1)[1] =
                                    ((npy_uint *)data0 + 2*1)[1] +
                                    ((npy_uint *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_uint *)data_out + 2*0)[0] =
                                    ((npy_uint *)data0 + 2*0)[0] +
                                    ((npy_uint *)data_out + 2*0)[0];
            ((npy_uint *)data_out + 2*0)[1] =
                                    ((npy_uint *)data0 + 2*0)[1] +
                                    ((npy_uint *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_uint *)data_out + 2*0)[0] =
                                ((npy_uint *)data0 + 2*0)[0] +
                                ((npy_uint *)data_out + 2*0)[0];
        ((npy_uint *)data_out + 2*0)[1] =
                                ((npy_uint *)data0 + 2*0)[1] +
                                ((npy_uint *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_uint *)data_out + 2*1)[0] =
                                ((npy_uint *)data0 + 2*1)[0] +
                                ((npy_uint *)data_out + 2*1)[0];
        ((npy_uint *)data_out + 2*1)[1] =
                                ((npy_uint *)data0 + 2*1)[1] +
                                ((npy_uint *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_uint *)data_out + 2*2)[0] =
                                ((npy_uint *)data0 + 2*2)[0] +
                                ((npy_uint *)data_out + 2*2)[0];
        ((npy_uint *)data_out + 2*2)[1] =
                                ((npy_uint *)data0 + 2*2)[1] +
                                ((npy_uint *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_uint *)data_out + 2*3)[0] =
                                ((npy_uint *)data0 + 2*3)[0] +
                                ((npy_uint *)data_out + 2*3)[0];
        ((npy_uint *)data_out + 2*3)[1] =
                                ((npy_uint *)data0 + 2*3)[1] +
                                ((npy_uint *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_uint *)data_out + 2*4)[0] =
                                ((npy_uint *)data0 + 2*4)[0] +
                                ((npy_uint *)data_out + 2*4)[0];
        ((npy_uint *)data_out + 2*4)[1] =
                                ((npy_uint *)data0 + 2*4)[1] +
                                ((npy_uint *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_uint *)data_out + 2*5)[0] =
                                ((npy_uint *)data0 + 2*5)[0] +
                                ((npy_uint *)data_out + 2*5)[0];
        ((npy_uint *)data_out + 2*5)[1] =
                                ((npy_uint *)data0 + 2*5)[1] +
                                ((npy_uint *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_uint *)data_out + 2*6)[0] =
                                ((npy_uint *)data0 + 2*6)[0] +
                                ((npy_uint *)data_out + 2*6)[0];
        ((npy_uint *)data_out + 2*6)[1] =
                                ((npy_uint *)data0 + 2*6)[1] +
                                ((npy_uint *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_uint *)data_out + 2*7)[0] =
                                ((npy_uint *)data0 + 2*7)[0] +
                                ((npy_uint *)data_out + 2*7)[0];
        ((npy_uint *)data_out + 2*7)[1] =
                                ((npy_uint *)data0 + 2*7)[1] +
                                ((npy_uint *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
uint_sum_of_products_muladd(npy_uint *data, npy_uint *data_out, npy_uint scalar, npy_intp count)
{
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u32;
    const npyv_u32 v_scalar = npyv_setall_u32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u32 b0 = npyv_loada_u32(data + vstep * 0);
            npyv_u32 c0 = npyv_loada_u32(data_out + vstep * 0);
            
#line 312
            npyv_u32 b1 = npyv_loada_u32(data + vstep * 1);
            npyv_u32 c1 = npyv_loada_u32(data_out + vstep * 1);
            
#line 312
            npyv_u32 b2 = npyv_loada_u32(data + vstep * 2);
            npyv_u32 c2 = npyv_loada_u32(data_out + vstep * 2);
            
#line 312
            npyv_u32 b3 = npyv_loada_u32(data + vstep * 3);
            npyv_u32 c3 = npyv_loada_u32(data_out + vstep * 3);
            
            #line 318
            npyv_u32 abc0 = npyv_muladd_u32(v_scalar, b0, c0);
            
#line 318
            npyv_u32 abc1 = npyv_muladd_u32(v_scalar, b1, c1);
            
#line 318
            npyv_u32 abc2 = npyv_muladd_u32(v_scalar, b2, c2);
            
#line 318
            npyv_u32 abc3 = npyv_muladd_u32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u32 b0 = npyv_load_u32(data + vstep * 0);
            npyv_u32 c0 = npyv_load_u32(data_out + vstep * 0);
            
#line 312
            npyv_u32 b1 = npyv_load_u32(data + vstep * 1);
            npyv_u32 c1 = npyv_load_u32(data_out + vstep * 1);
            
#line 312
            npyv_u32 b2 = npyv_load_u32(data + vstep * 2);
            npyv_u32 c2 = npyv_load_u32(data_out + vstep * 2);
            
#line 312
            npyv_u32 b3 = npyv_load_u32(data + vstep * 3);
            npyv_u32 c3 = npyv_load_u32(data_out + vstep * 3);
            
            #line 318
            npyv_u32 abc0 = npyv_muladd_u32(v_scalar, b0, c0);
            
#line 318
            npyv_u32 abc1 = npyv_muladd_u32(v_scalar, b1, c1);
            
#line 318
            npyv_u32 abc2 = npyv_muladd_u32(v_scalar, b2, c2);
            
#line 318
            npyv_u32 abc3 = npyv_muladd_u32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data, count);
        npyv_u32 b = npyv_load_tillz_u32(data_out, count);
        npyv_store_till_u32(data_out, count, npyv_muladd_u32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_uint b0 = (data[0]);
        const npy_uint c0 = (data_out[0]);
        
#line 340
        const npy_uint b1 = (data[1]);
        const npy_uint c1 = (data_out[1]);
        
#line 340
        const npy_uint b2 = (data[2]);
        const npy_uint c2 = (data_out[2]);
        
#line 340
        const npy_uint b3 = (data[3]);
        const npy_uint c3 = (data_out[3]);
        
        #line 346
        const npy_uint abc0 = scalar * b0 + c0;
        
#line 346
        const npy_uint abc1 = scalar * b1 + c1;
        
#line 346
        const npy_uint abc2 = scalar * b2 + c2;
        
#line 346
        const npy_uint abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_uint b = (*data);
        const npy_uint c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_uint
}

static void
uint_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data_out = (npy_uint *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_uint
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u32 a0 = npyv_loada_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_loada_u32(data1 + vstep * 0);
            npyv_u32 c0 = npyv_loada_u32(data_out + vstep * 0);
            
#line 390
            npyv_u32 a1 = npyv_loada_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_loada_u32(data1 + vstep * 1);
            npyv_u32 c1 = npyv_loada_u32(data_out + vstep * 1);
            
#line 390
            npyv_u32 a2 = npyv_loada_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_loada_u32(data1 + vstep * 2);
            npyv_u32 c2 = npyv_loada_u32(data_out + vstep * 2);
            
#line 390
            npyv_u32 a3 = npyv_loada_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_loada_u32(data1 + vstep * 3);
            npyv_u32 c3 = npyv_loada_u32(data_out + vstep * 3);
            
            #line 397
            npyv_u32 abc0 = npyv_muladd_u32(a0, b0, c0);
            
#line 397
            npyv_u32 abc1 = npyv_muladd_u32(a1, b1, c1);
            
#line 397
            npyv_u32 abc2 = npyv_muladd_u32(a2, b2, c2);
            
#line 397
            npyv_u32 abc3 = npyv_muladd_u32(a3, b3, c3);
            
            #line 402
            npyv_storea_u32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u32 a0 = npyv_load_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_load_u32(data1 + vstep * 0);
            npyv_u32 c0 = npyv_load_u32(data_out + vstep * 0);
            
#line 390
            npyv_u32 a1 = npyv_load_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_load_u32(data1 + vstep * 1);
            npyv_u32 c1 = npyv_load_u32(data_out + vstep * 1);
            
#line 390
            npyv_u32 a2 = npyv_load_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_load_u32(data1 + vstep * 2);
            npyv_u32 c2 = npyv_load_u32(data_out + vstep * 2);
            
#line 390
            npyv_u32 a3 = npyv_load_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_load_u32(data1 + vstep * 3);
            npyv_u32 c3 = npyv_load_u32(data_out + vstep * 3);
            
            #line 397
            npyv_u32 abc0 = npyv_muladd_u32(a0, b0, c0);
            
#line 397
            npyv_u32 abc1 = npyv_muladd_u32(a1, b1, c1);
            
#line 397
            npyv_u32 abc2 = npyv_muladd_u32(a2, b2, c2);
            
#line 397
            npyv_u32 abc3 = npyv_muladd_u32(a3, b3, c3);
            
            #line 402
            npyv_store_u32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data0, count);
        npyv_u32 b = npyv_load_tillz_u32(data1, count);
        npyv_u32 c = npyv_load_tillz_u32(data_out, count);
        npyv_store_till_u32(data_out, count, npyv_muladd_u32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_uint a0 = (data0[0]);
        const npy_uint b0 = (data1[0]);
        const npy_uint c0 = (data_out[0]);
        
#line 420
        const npy_uint a1 = (data0[1]);
        const npy_uint b1 = (data1[1]);
        const npy_uint c1 = (data_out[1]);
        
#line 420
        const npy_uint a2 = (data0[2]);
        const npy_uint b2 = (data1[2]);
        const npy_uint c2 = (data_out[2]);
        
#line 420
        const npy_uint a3 = (data0[3]);
        const npy_uint b3 = (data1[3]);
        const npy_uint c3 = (data_out[3]);
        
        #line 427
        const npy_uint abc0 = a0 * b0 + c0;
        
#line 427
        const npy_uint abc1 = a1 * b1 + c1;
        
#line 427
        const npy_uint abc2 = a2 * b2 + c2;
        
#line 427
        const npy_uint abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_uint a = (*data0);
        const npy_uint b = (*data1);
        const npy_uint c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_uint

}

/* Some extra specializations for the two operand case */
static void
uint_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint value0 = (*(npy_uint *)dataptr[0]);
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data_out = (npy_uint *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    uint_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
uint_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint value1 = (*(npy_uint *)dataptr[1]);
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data_out = (npy_uint *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    uint_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint accum = 0;

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u32;
    npyv_u32 v_accum = npyv_zero_u32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u32 a0 = npyv_loada_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_loada_u32(data1 + vstep * 0);
            
#line 501
            npyv_u32 a1 = npyv_loada_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_loada_u32(data1 + vstep * 1);
            
#line 501
            npyv_u32 a2 = npyv_loada_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_loada_u32(data1 + vstep * 2);
            
#line 501
            npyv_u32 a3 = npyv_loada_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_loada_u32(data1 + vstep * 3);
            
            npyv_u32 ab3 = npyv_muladd_u32(a3, b3, v_accum);
            npyv_u32 ab2 = npyv_muladd_u32(a2, b2, ab3);
            npyv_u32 ab1 = npyv_muladd_u32(a1, b1, ab2);
                   v_accum = npyv_muladd_u32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u32 a0 = npyv_load_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_load_u32(data1 + vstep * 0);
            
#line 501
            npyv_u32 a1 = npyv_load_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_load_u32(data1 + vstep * 1);
            
#line 501
            npyv_u32 a2 = npyv_load_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_load_u32(data1 + vstep * 2);
            
#line 501
            npyv_u32 a3 = npyv_load_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_load_u32(data1 + vstep * 3);
            
            npyv_u32 ab3 = npyv_muladd_u32(a3, b3, v_accum);
            npyv_u32 ab2 = npyv_muladd_u32(a2, b2, ab3);
            npyv_u32 ab1 = npyv_muladd_u32(a1, b1, ab2);
                   v_accum = npyv_muladd_u32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data0, count);
        npyv_u32 b = npyv_load_tillz_u32(data1, count);
        v_accum = npyv_muladd_u32(a, b, v_accum);
    }
    accum = npyv_sum_u32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_uint ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_uint ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_uint ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_uint ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_uint a = (*data0);
        const npy_uint b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_uint
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint value0 = (*(npy_uint *)dataptr[0]);
    npy_uint accum = uint_sum_of_arr(data1, count);
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint value1 = (*(npy_uint *)dataptr[1]);
    npy_uint accum = uint_sum_of_arr(data0, count);
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
uint_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data2 = (npy_uint *)dataptr[2];
    npy_uint *data_out = (npy_uint *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
uint_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        *(npy_uint *)dataptr[nop] = (temp +
                                           (*(npy_uint *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_uint);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_uint *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[0];
        ((npy_uint *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_uint);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_uint *data = (npy_uint *)dataptr[0];
    npy_uint accum = uint_sum_of_arr(data, count);
    *((npy_uint *)dataptr[1]) = (accum + (*((npy_uint *)dataptr[1])));
#else
    npy_uint accum_re = 0, accum_im = 0;
    npy_uint *data0 = (npy_uint *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_uint re01 = data0[0] + data0[2];
        const npy_uint re23 = data0[4] + data0[6];
        const npy_uint im13 = data0[1] + data0[3];
        const npy_uint im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_uint *)dataptr[1])[0] += accum_re;
    ((npy_uint *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
uint_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_uint accum_re = 0, accum_im = 0;
#else
    npy_uint accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_uint *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_uint *)data0) *
                 (*(npy_uint *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_uint *)data0) *
                 (*(npy_uint *)data1) *
                 (*(npy_uint *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_uint *)data0)[0];
        accum_im += ((npy_uint *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_uint *)dataptr[2])[0] += accum_re;
    ((npy_uint *)dataptr[2])[1] += accum_im;
#  else
    ((npy_uint *)dataptr[nop])[0] += accum_re;
    ((npy_uint *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_uint *)dataptr[2]) = (accum +
                                    (*((npy_uint *)dataptr[2])));
#  else
    *((npy_uint *)dataptr[nop]) = (accum +
                                    (*((npy_uint *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
uint_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_uint *)data_out = ((*(npy_uint *)data0) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_uint *)data_out = ((*(npy_uint *)data0) *
                                         (*(npy_uint *)data1) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_uint *)data_out = ((*(npy_uint *)data0) *
                                         (*(npy_uint *)data1) *
                                         (*(npy_uint *)data2) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        *(npy_uint *)dataptr[nop] = (temp +
                                           (*(npy_uint *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_uint *)data_out)[0] = ((npy_uint *)data0)[0] +
                                         ((npy_uint *)data_out)[0];
        ((npy_uint *)data_out)[1] = ((npy_uint *)data0)[1] +
                                         ((npy_uint *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_uint *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[0];
        ((npy_uint *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
uint_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data_out = (npy_uint *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_uint *)data_out + 2*6)[0] =
                                    ((npy_uint *)data0 + 2*6)[0] +
                                    ((npy_uint *)data_out + 2*6)[0];
            ((npy_uint *)data_out + 2*6)[1] =
                                    ((npy_uint *)data0 + 2*6)[1] +
                                    ((npy_uint *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_uint *)data_out + 2*5)[0] =
                                    ((npy_uint *)data0 + 2*5)[0] +
                                    ((npy_uint *)data_out + 2*5)[0];
            ((npy_uint *)data_out + 2*5)[1] =
                                    ((npy_uint *)data0 + 2*5)[1] +
                                    ((npy_uint *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_uint *)data_out + 2*4)[0] =
                                    ((npy_uint *)data0 + 2*4)[0] +
                                    ((npy_uint *)data_out + 2*4)[0];
            ((npy_uint *)data_out + 2*4)[1] =
                                    ((npy_uint *)data0 + 2*4)[1] +
                                    ((npy_uint *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_uint *)data_out + 2*3)[0] =
                                    ((npy_uint *)data0 + 2*3)[0] +
                                    ((npy_uint *)data_out + 2*3)[0];
            ((npy_uint *)data_out + 2*3)[1] =
                                    ((npy_uint *)data0 + 2*3)[1] +
                                    ((npy_uint *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_uint *)data_out + 2*2)[0] =
                                    ((npy_uint *)data0 + 2*2)[0] +
                                    ((npy_uint *)data_out + 2*2)[0];
            ((npy_uint *)data_out + 2*2)[1] =
                                    ((npy_uint *)data0 + 2*2)[1] +
                                    ((npy_uint *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_uint *)data_out + 2*1)[0] =
                                    ((npy_uint *)data0 + 2*1)[0] +
                                    ((npy_uint *)data_out + 2*1)[0];
            ((npy_uint *)data_out + 2*1)[1] =
                                    ((npy_uint *)data0 + 2*1)[1] +
                                    ((npy_uint *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_uint *)data_out + 2*0)[0] =
                                    ((npy_uint *)data0 + 2*0)[0] +
                                    ((npy_uint *)data_out + 2*0)[0];
            ((npy_uint *)data_out + 2*0)[1] =
                                    ((npy_uint *)data0 + 2*0)[1] +
                                    ((npy_uint *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_uint *)data_out + 2*0)[0] =
                                ((npy_uint *)data0 + 2*0)[0] +
                                ((npy_uint *)data_out + 2*0)[0];
        ((npy_uint *)data_out + 2*0)[1] =
                                ((npy_uint *)data0 + 2*0)[1] +
                                ((npy_uint *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_uint *)data_out + 2*1)[0] =
                                ((npy_uint *)data0 + 2*1)[0] +
                                ((npy_uint *)data_out + 2*1)[0];
        ((npy_uint *)data_out + 2*1)[1] =
                                ((npy_uint *)data0 + 2*1)[1] +
                                ((npy_uint *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_uint *)data_out + 2*2)[0] =
                                ((npy_uint *)data0 + 2*2)[0] +
                                ((npy_uint *)data_out + 2*2)[0];
        ((npy_uint *)data_out + 2*2)[1] =
                                ((npy_uint *)data0 + 2*2)[1] +
                                ((npy_uint *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_uint *)data_out + 2*3)[0] =
                                ((npy_uint *)data0 + 2*3)[0] +
                                ((npy_uint *)data_out + 2*3)[0];
        ((npy_uint *)data_out + 2*3)[1] =
                                ((npy_uint *)data0 + 2*3)[1] +
                                ((npy_uint *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_uint *)data_out + 2*4)[0] =
                                ((npy_uint *)data0 + 2*4)[0] +
                                ((npy_uint *)data_out + 2*4)[0];
        ((npy_uint *)data_out + 2*4)[1] =
                                ((npy_uint *)data0 + 2*4)[1] +
                                ((npy_uint *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_uint *)data_out + 2*5)[0] =
                                ((npy_uint *)data0 + 2*5)[0] +
                                ((npy_uint *)data_out + 2*5)[0];
        ((npy_uint *)data_out + 2*5)[1] =
                                ((npy_uint *)data0 + 2*5)[1] +
                                ((npy_uint *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_uint *)data_out + 2*6)[0] =
                                ((npy_uint *)data0 + 2*6)[0] +
                                ((npy_uint *)data_out + 2*6)[0];
        ((npy_uint *)data_out + 2*6)[1] =
                                ((npy_uint *)data0 + 2*6)[1] +
                                ((npy_uint *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_uint *)data_out + 2*7)[0] =
                                ((npy_uint *)data0 + 2*7)[0] +
                                ((npy_uint *)data_out + 2*7)[0];
        ((npy_uint *)data_out + 2*7)[1] =
                                ((npy_uint *)data0 + 2*7)[1] +
                                ((npy_uint *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
uint_sum_of_products_muladd(npy_uint *data, npy_uint *data_out, npy_uint scalar, npy_intp count)
{
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u32;
    const npyv_u32 v_scalar = npyv_setall_u32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u32 b0 = npyv_loada_u32(data + vstep * 0);
            npyv_u32 c0 = npyv_loada_u32(data_out + vstep * 0);
            
#line 312
            npyv_u32 b1 = npyv_loada_u32(data + vstep * 1);
            npyv_u32 c1 = npyv_loada_u32(data_out + vstep * 1);
            
#line 312
            npyv_u32 b2 = npyv_loada_u32(data + vstep * 2);
            npyv_u32 c2 = npyv_loada_u32(data_out + vstep * 2);
            
#line 312
            npyv_u32 b3 = npyv_loada_u32(data + vstep * 3);
            npyv_u32 c3 = npyv_loada_u32(data_out + vstep * 3);
            
            #line 318
            npyv_u32 abc0 = npyv_muladd_u32(v_scalar, b0, c0);
            
#line 318
            npyv_u32 abc1 = npyv_muladd_u32(v_scalar, b1, c1);
            
#line 318
            npyv_u32 abc2 = npyv_muladd_u32(v_scalar, b2, c2);
            
#line 318
            npyv_u32 abc3 = npyv_muladd_u32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u32 b0 = npyv_load_u32(data + vstep * 0);
            npyv_u32 c0 = npyv_load_u32(data_out + vstep * 0);
            
#line 312
            npyv_u32 b1 = npyv_load_u32(data + vstep * 1);
            npyv_u32 c1 = npyv_load_u32(data_out + vstep * 1);
            
#line 312
            npyv_u32 b2 = npyv_load_u32(data + vstep * 2);
            npyv_u32 c2 = npyv_load_u32(data_out + vstep * 2);
            
#line 312
            npyv_u32 b3 = npyv_load_u32(data + vstep * 3);
            npyv_u32 c3 = npyv_load_u32(data_out + vstep * 3);
            
            #line 318
            npyv_u32 abc0 = npyv_muladd_u32(v_scalar, b0, c0);
            
#line 318
            npyv_u32 abc1 = npyv_muladd_u32(v_scalar, b1, c1);
            
#line 318
            npyv_u32 abc2 = npyv_muladd_u32(v_scalar, b2, c2);
            
#line 318
            npyv_u32 abc3 = npyv_muladd_u32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data, count);
        npyv_u32 b = npyv_load_tillz_u32(data_out, count);
        npyv_store_till_u32(data_out, count, npyv_muladd_u32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_uint b0 = (data[0]);
        const npy_uint c0 = (data_out[0]);
        
#line 340
        const npy_uint b1 = (data[1]);
        const npy_uint c1 = (data_out[1]);
        
#line 340
        const npy_uint b2 = (data[2]);
        const npy_uint c2 = (data_out[2]);
        
#line 340
        const npy_uint b3 = (data[3]);
        const npy_uint c3 = (data_out[3]);
        
        #line 346
        const npy_uint abc0 = scalar * b0 + c0;
        
#line 346
        const npy_uint abc1 = scalar * b1 + c1;
        
#line 346
        const npy_uint abc2 = scalar * b2 + c2;
        
#line 346
        const npy_uint abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_uint b = (*data);
        const npy_uint c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_uint
}

static void
uint_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data_out = (npy_uint *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_uint
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u32 a0 = npyv_loada_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_loada_u32(data1 + vstep * 0);
            npyv_u32 c0 = npyv_loada_u32(data_out + vstep * 0);
            
#line 390
            npyv_u32 a1 = npyv_loada_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_loada_u32(data1 + vstep * 1);
            npyv_u32 c1 = npyv_loada_u32(data_out + vstep * 1);
            
#line 390
            npyv_u32 a2 = npyv_loada_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_loada_u32(data1 + vstep * 2);
            npyv_u32 c2 = npyv_loada_u32(data_out + vstep * 2);
            
#line 390
            npyv_u32 a3 = npyv_loada_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_loada_u32(data1 + vstep * 3);
            npyv_u32 c3 = npyv_loada_u32(data_out + vstep * 3);
            
            #line 397
            npyv_u32 abc0 = npyv_muladd_u32(a0, b0, c0);
            
#line 397
            npyv_u32 abc1 = npyv_muladd_u32(a1, b1, c1);
            
#line 397
            npyv_u32 abc2 = npyv_muladd_u32(a2, b2, c2);
            
#line 397
            npyv_u32 abc3 = npyv_muladd_u32(a3, b3, c3);
            
            #line 402
            npyv_storea_u32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u32 a0 = npyv_load_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_load_u32(data1 + vstep * 0);
            npyv_u32 c0 = npyv_load_u32(data_out + vstep * 0);
            
#line 390
            npyv_u32 a1 = npyv_load_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_load_u32(data1 + vstep * 1);
            npyv_u32 c1 = npyv_load_u32(data_out + vstep * 1);
            
#line 390
            npyv_u32 a2 = npyv_load_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_load_u32(data1 + vstep * 2);
            npyv_u32 c2 = npyv_load_u32(data_out + vstep * 2);
            
#line 390
            npyv_u32 a3 = npyv_load_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_load_u32(data1 + vstep * 3);
            npyv_u32 c3 = npyv_load_u32(data_out + vstep * 3);
            
            #line 397
            npyv_u32 abc0 = npyv_muladd_u32(a0, b0, c0);
            
#line 397
            npyv_u32 abc1 = npyv_muladd_u32(a1, b1, c1);
            
#line 397
            npyv_u32 abc2 = npyv_muladd_u32(a2, b2, c2);
            
#line 397
            npyv_u32 abc3 = npyv_muladd_u32(a3, b3, c3);
            
            #line 402
            npyv_store_u32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data0, count);
        npyv_u32 b = npyv_load_tillz_u32(data1, count);
        npyv_u32 c = npyv_load_tillz_u32(data_out, count);
        npyv_store_till_u32(data_out, count, npyv_muladd_u32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_uint a0 = (data0[0]);
        const npy_uint b0 = (data1[0]);
        const npy_uint c0 = (data_out[0]);
        
#line 420
        const npy_uint a1 = (data0[1]);
        const npy_uint b1 = (data1[1]);
        const npy_uint c1 = (data_out[1]);
        
#line 420
        const npy_uint a2 = (data0[2]);
        const npy_uint b2 = (data1[2]);
        const npy_uint c2 = (data_out[2]);
        
#line 420
        const npy_uint a3 = (data0[3]);
        const npy_uint b3 = (data1[3]);
        const npy_uint c3 = (data_out[3]);
        
        #line 427
        const npy_uint abc0 = a0 * b0 + c0;
        
#line 427
        const npy_uint abc1 = a1 * b1 + c1;
        
#line 427
        const npy_uint abc2 = a2 * b2 + c2;
        
#line 427
        const npy_uint abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_uint a = (*data0);
        const npy_uint b = (*data1);
        const npy_uint c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_uint

}

/* Some extra specializations for the two operand case */
static void
uint_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint value0 = (*(npy_uint *)dataptr[0]);
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data_out = (npy_uint *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    uint_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
uint_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint value1 = (*(npy_uint *)dataptr[1]);
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data_out = (npy_uint *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    uint_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint accum = 0;

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u32;
    npyv_u32 v_accum = npyv_zero_u32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u32 a0 = npyv_loada_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_loada_u32(data1 + vstep * 0);
            
#line 501
            npyv_u32 a1 = npyv_loada_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_loada_u32(data1 + vstep * 1);
            
#line 501
            npyv_u32 a2 = npyv_loada_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_loada_u32(data1 + vstep * 2);
            
#line 501
            npyv_u32 a3 = npyv_loada_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_loada_u32(data1 + vstep * 3);
            
            npyv_u32 ab3 = npyv_muladd_u32(a3, b3, v_accum);
            npyv_u32 ab2 = npyv_muladd_u32(a2, b2, ab3);
            npyv_u32 ab1 = npyv_muladd_u32(a1, b1, ab2);
                   v_accum = npyv_muladd_u32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u32 a0 = npyv_load_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_load_u32(data1 + vstep * 0);
            
#line 501
            npyv_u32 a1 = npyv_load_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_load_u32(data1 + vstep * 1);
            
#line 501
            npyv_u32 a2 = npyv_load_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_load_u32(data1 + vstep * 2);
            
#line 501
            npyv_u32 a3 = npyv_load_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_load_u32(data1 + vstep * 3);
            
            npyv_u32 ab3 = npyv_muladd_u32(a3, b3, v_accum);
            npyv_u32 ab2 = npyv_muladd_u32(a2, b2, ab3);
            npyv_u32 ab1 = npyv_muladd_u32(a1, b1, ab2);
                   v_accum = npyv_muladd_u32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data0, count);
        npyv_u32 b = npyv_load_tillz_u32(data1, count);
        v_accum = npyv_muladd_u32(a, b, v_accum);
    }
    accum = npyv_sum_u32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_uint ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_uint ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_uint ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_uint ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_uint a = (*data0);
        const npy_uint b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_uint
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint value0 = (*(npy_uint *)dataptr[0]);
    npy_uint accum = uint_sum_of_arr(data1, count);
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint value1 = (*(npy_uint *)dataptr[1]);
    npy_uint accum = uint_sum_of_arr(data0, count);
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
uint_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data2 = (npy_uint *)dataptr[2];
    npy_uint *data_out = (npy_uint *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
uint_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        *(npy_uint *)dataptr[nop] = (temp +
                                           (*(npy_uint *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_uint);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_uint *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[0];
        ((npy_uint *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_uint);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_uint *data = (npy_uint *)dataptr[0];
    npy_uint accum = uint_sum_of_arr(data, count);
    *((npy_uint *)dataptr[1]) = (accum + (*((npy_uint *)dataptr[1])));
#else
    npy_uint accum_re = 0, accum_im = 0;
    npy_uint *data0 = (npy_uint *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_uint re01 = data0[0] + data0[2];
        const npy_uint re23 = data0[4] + data0[6];
        const npy_uint im13 = data0[1] + data0[3];
        const npy_uint im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_uint *)dataptr[1])[0] += accum_re;
    ((npy_uint *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
uint_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_uint accum_re = 0, accum_im = 0;
#else
    npy_uint accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_uint *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_uint *)data0) *
                 (*(npy_uint *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_uint *)data0) *
                 (*(npy_uint *)data1) *
                 (*(npy_uint *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_uint *)data0)[0];
        accum_im += ((npy_uint *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_uint *)dataptr[3])[0] += accum_re;
    ((npy_uint *)dataptr[3])[1] += accum_im;
#  else
    ((npy_uint *)dataptr[nop])[0] += accum_re;
    ((npy_uint *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_uint *)dataptr[3]) = (accum +
                                    (*((npy_uint *)dataptr[3])));
#  else
    *((npy_uint *)dataptr[nop]) = (accum +
                                    (*((npy_uint *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
uint_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_uint *)data_out = ((*(npy_uint *)data0) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_uint *)data_out = ((*(npy_uint *)data0) *
                                         (*(npy_uint *)data1) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_uint *)data_out = ((*(npy_uint *)data0) *
                                         (*(npy_uint *)data1) *
                                         (*(npy_uint *)data2) +
                                         (*(npy_uint *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        *(npy_uint *)dataptr[nop] = (temp +
                                           (*(npy_uint *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_uint *)data_out)[0] = ((npy_uint *)data0)[0] +
                                         ((npy_uint *)data_out)[0];
        ((npy_uint *)data_out)[1] = ((npy_uint *)data0)[1] +
                                         ((npy_uint *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_uint *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[0];
        ((npy_uint *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
uint_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data_out = (npy_uint *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_uint *)data_out + 2*6)[0] =
                                    ((npy_uint *)data0 + 2*6)[0] +
                                    ((npy_uint *)data_out + 2*6)[0];
            ((npy_uint *)data_out + 2*6)[1] =
                                    ((npy_uint *)data0 + 2*6)[1] +
                                    ((npy_uint *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_uint *)data_out + 2*5)[0] =
                                    ((npy_uint *)data0 + 2*5)[0] +
                                    ((npy_uint *)data_out + 2*5)[0];
            ((npy_uint *)data_out + 2*5)[1] =
                                    ((npy_uint *)data0 + 2*5)[1] +
                                    ((npy_uint *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_uint *)data_out + 2*4)[0] =
                                    ((npy_uint *)data0 + 2*4)[0] +
                                    ((npy_uint *)data_out + 2*4)[0];
            ((npy_uint *)data_out + 2*4)[1] =
                                    ((npy_uint *)data0 + 2*4)[1] +
                                    ((npy_uint *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_uint *)data_out + 2*3)[0] =
                                    ((npy_uint *)data0 + 2*3)[0] +
                                    ((npy_uint *)data_out + 2*3)[0];
            ((npy_uint *)data_out + 2*3)[1] =
                                    ((npy_uint *)data0 + 2*3)[1] +
                                    ((npy_uint *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_uint *)data_out + 2*2)[0] =
                                    ((npy_uint *)data0 + 2*2)[0] +
                                    ((npy_uint *)data_out + 2*2)[0];
            ((npy_uint *)data_out + 2*2)[1] =
                                    ((npy_uint *)data0 + 2*2)[1] +
                                    ((npy_uint *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_uint *)data_out + 2*1)[0] =
                                    ((npy_uint *)data0 + 2*1)[0] +
                                    ((npy_uint *)data_out + 2*1)[0];
            ((npy_uint *)data_out + 2*1)[1] =
                                    ((npy_uint *)data0 + 2*1)[1] +
                                    ((npy_uint *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_uint *)data_out + 2*0)[0] =
                                    ((npy_uint *)data0 + 2*0)[0] +
                                    ((npy_uint *)data_out + 2*0)[0];
            ((npy_uint *)data_out + 2*0)[1] =
                                    ((npy_uint *)data0 + 2*0)[1] +
                                    ((npy_uint *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_uint *)data_out + 2*0)[0] =
                                ((npy_uint *)data0 + 2*0)[0] +
                                ((npy_uint *)data_out + 2*0)[0];
        ((npy_uint *)data_out + 2*0)[1] =
                                ((npy_uint *)data0 + 2*0)[1] +
                                ((npy_uint *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_uint *)data_out + 2*1)[0] =
                                ((npy_uint *)data0 + 2*1)[0] +
                                ((npy_uint *)data_out + 2*1)[0];
        ((npy_uint *)data_out + 2*1)[1] =
                                ((npy_uint *)data0 + 2*1)[1] +
                                ((npy_uint *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_uint *)data_out + 2*2)[0] =
                                ((npy_uint *)data0 + 2*2)[0] +
                                ((npy_uint *)data_out + 2*2)[0];
        ((npy_uint *)data_out + 2*2)[1] =
                                ((npy_uint *)data0 + 2*2)[1] +
                                ((npy_uint *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_uint *)data_out + 2*3)[0] =
                                ((npy_uint *)data0 + 2*3)[0] +
                                ((npy_uint *)data_out + 2*3)[0];
        ((npy_uint *)data_out + 2*3)[1] =
                                ((npy_uint *)data0 + 2*3)[1] +
                                ((npy_uint *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_uint *)data_out + 2*4)[0] =
                                ((npy_uint *)data0 + 2*4)[0] +
                                ((npy_uint *)data_out + 2*4)[0];
        ((npy_uint *)data_out + 2*4)[1] =
                                ((npy_uint *)data0 + 2*4)[1] +
                                ((npy_uint *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_uint *)data_out + 2*5)[0] =
                                ((npy_uint *)data0 + 2*5)[0] +
                                ((npy_uint *)data_out + 2*5)[0];
        ((npy_uint *)data_out + 2*5)[1] =
                                ((npy_uint *)data0 + 2*5)[1] +
                                ((npy_uint *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_uint *)data_out + 2*6)[0] =
                                ((npy_uint *)data0 + 2*6)[0] +
                                ((npy_uint *)data_out + 2*6)[0];
        ((npy_uint *)data_out + 2*6)[1] =
                                ((npy_uint *)data0 + 2*6)[1] +
                                ((npy_uint *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_uint *)data_out + 2*7)[0] =
                                ((npy_uint *)data0 + 2*7)[0] +
                                ((npy_uint *)data_out + 2*7)[0];
        ((npy_uint *)data_out + 2*7)[1] =
                                ((npy_uint *)data0 + 2*7)[1] +
                                ((npy_uint *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
uint_sum_of_products_muladd(npy_uint *data, npy_uint *data_out, npy_uint scalar, npy_intp count)
{
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u32;
    const npyv_u32 v_scalar = npyv_setall_u32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u32 b0 = npyv_loada_u32(data + vstep * 0);
            npyv_u32 c0 = npyv_loada_u32(data_out + vstep * 0);
            
#line 312
            npyv_u32 b1 = npyv_loada_u32(data + vstep * 1);
            npyv_u32 c1 = npyv_loada_u32(data_out + vstep * 1);
            
#line 312
            npyv_u32 b2 = npyv_loada_u32(data + vstep * 2);
            npyv_u32 c2 = npyv_loada_u32(data_out + vstep * 2);
            
#line 312
            npyv_u32 b3 = npyv_loada_u32(data + vstep * 3);
            npyv_u32 c3 = npyv_loada_u32(data_out + vstep * 3);
            
            #line 318
            npyv_u32 abc0 = npyv_muladd_u32(v_scalar, b0, c0);
            
#line 318
            npyv_u32 abc1 = npyv_muladd_u32(v_scalar, b1, c1);
            
#line 318
            npyv_u32 abc2 = npyv_muladd_u32(v_scalar, b2, c2);
            
#line 318
            npyv_u32 abc3 = npyv_muladd_u32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u32 b0 = npyv_load_u32(data + vstep * 0);
            npyv_u32 c0 = npyv_load_u32(data_out + vstep * 0);
            
#line 312
            npyv_u32 b1 = npyv_load_u32(data + vstep * 1);
            npyv_u32 c1 = npyv_load_u32(data_out + vstep * 1);
            
#line 312
            npyv_u32 b2 = npyv_load_u32(data + vstep * 2);
            npyv_u32 c2 = npyv_load_u32(data_out + vstep * 2);
            
#line 312
            npyv_u32 b3 = npyv_load_u32(data + vstep * 3);
            npyv_u32 c3 = npyv_load_u32(data_out + vstep * 3);
            
            #line 318
            npyv_u32 abc0 = npyv_muladd_u32(v_scalar, b0, c0);
            
#line 318
            npyv_u32 abc1 = npyv_muladd_u32(v_scalar, b1, c1);
            
#line 318
            npyv_u32 abc2 = npyv_muladd_u32(v_scalar, b2, c2);
            
#line 318
            npyv_u32 abc3 = npyv_muladd_u32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data, count);
        npyv_u32 b = npyv_load_tillz_u32(data_out, count);
        npyv_store_till_u32(data_out, count, npyv_muladd_u32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_uint b0 = (data[0]);
        const npy_uint c0 = (data_out[0]);
        
#line 340
        const npy_uint b1 = (data[1]);
        const npy_uint c1 = (data_out[1]);
        
#line 340
        const npy_uint b2 = (data[2]);
        const npy_uint c2 = (data_out[2]);
        
#line 340
        const npy_uint b3 = (data[3]);
        const npy_uint c3 = (data_out[3]);
        
        #line 346
        const npy_uint abc0 = scalar * b0 + c0;
        
#line 346
        const npy_uint abc1 = scalar * b1 + c1;
        
#line 346
        const npy_uint abc2 = scalar * b2 + c2;
        
#line 346
        const npy_uint abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_uint b = (*data);
        const npy_uint c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_uint
}

static void
uint_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data_out = (npy_uint *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_uint
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u32 a0 = npyv_loada_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_loada_u32(data1 + vstep * 0);
            npyv_u32 c0 = npyv_loada_u32(data_out + vstep * 0);
            
#line 390
            npyv_u32 a1 = npyv_loada_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_loada_u32(data1 + vstep * 1);
            npyv_u32 c1 = npyv_loada_u32(data_out + vstep * 1);
            
#line 390
            npyv_u32 a2 = npyv_loada_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_loada_u32(data1 + vstep * 2);
            npyv_u32 c2 = npyv_loada_u32(data_out + vstep * 2);
            
#line 390
            npyv_u32 a3 = npyv_loada_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_loada_u32(data1 + vstep * 3);
            npyv_u32 c3 = npyv_loada_u32(data_out + vstep * 3);
            
            #line 397
            npyv_u32 abc0 = npyv_muladd_u32(a0, b0, c0);
            
#line 397
            npyv_u32 abc1 = npyv_muladd_u32(a1, b1, c1);
            
#line 397
            npyv_u32 abc2 = npyv_muladd_u32(a2, b2, c2);
            
#line 397
            npyv_u32 abc3 = npyv_muladd_u32(a3, b3, c3);
            
            #line 402
            npyv_storea_u32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u32 a0 = npyv_load_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_load_u32(data1 + vstep * 0);
            npyv_u32 c0 = npyv_load_u32(data_out + vstep * 0);
            
#line 390
            npyv_u32 a1 = npyv_load_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_load_u32(data1 + vstep * 1);
            npyv_u32 c1 = npyv_load_u32(data_out + vstep * 1);
            
#line 390
            npyv_u32 a2 = npyv_load_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_load_u32(data1 + vstep * 2);
            npyv_u32 c2 = npyv_load_u32(data_out + vstep * 2);
            
#line 390
            npyv_u32 a3 = npyv_load_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_load_u32(data1 + vstep * 3);
            npyv_u32 c3 = npyv_load_u32(data_out + vstep * 3);
            
            #line 397
            npyv_u32 abc0 = npyv_muladd_u32(a0, b0, c0);
            
#line 397
            npyv_u32 abc1 = npyv_muladd_u32(a1, b1, c1);
            
#line 397
            npyv_u32 abc2 = npyv_muladd_u32(a2, b2, c2);
            
#line 397
            npyv_u32 abc3 = npyv_muladd_u32(a3, b3, c3);
            
            #line 402
            npyv_store_u32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data0, count);
        npyv_u32 b = npyv_load_tillz_u32(data1, count);
        npyv_u32 c = npyv_load_tillz_u32(data_out, count);
        npyv_store_till_u32(data_out, count, npyv_muladd_u32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_uint a0 = (data0[0]);
        const npy_uint b0 = (data1[0]);
        const npy_uint c0 = (data_out[0]);
        
#line 420
        const npy_uint a1 = (data0[1]);
        const npy_uint b1 = (data1[1]);
        const npy_uint c1 = (data_out[1]);
        
#line 420
        const npy_uint a2 = (data0[2]);
        const npy_uint b2 = (data1[2]);
        const npy_uint c2 = (data_out[2]);
        
#line 420
        const npy_uint a3 = (data0[3]);
        const npy_uint b3 = (data1[3]);
        const npy_uint c3 = (data_out[3]);
        
        #line 427
        const npy_uint abc0 = a0 * b0 + c0;
        
#line 427
        const npy_uint abc1 = a1 * b1 + c1;
        
#line 427
        const npy_uint abc2 = a2 * b2 + c2;
        
#line 427
        const npy_uint abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_uint a = (*data0);
        const npy_uint b = (*data1);
        const npy_uint c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_uint

}

/* Some extra specializations for the two operand case */
static void
uint_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint value0 = (*(npy_uint *)dataptr[0]);
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data_out = (npy_uint *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    uint_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
uint_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint value1 = (*(npy_uint *)dataptr[1]);
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data_out = (npy_uint *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    uint_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint accum = 0;

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_uint
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u32;
    npyv_u32 v_accum = npyv_zero_u32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u32 a0 = npyv_loada_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_loada_u32(data1 + vstep * 0);
            
#line 501
            npyv_u32 a1 = npyv_loada_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_loada_u32(data1 + vstep * 1);
            
#line 501
            npyv_u32 a2 = npyv_loada_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_loada_u32(data1 + vstep * 2);
            
#line 501
            npyv_u32 a3 = npyv_loada_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_loada_u32(data1 + vstep * 3);
            
            npyv_u32 ab3 = npyv_muladd_u32(a3, b3, v_accum);
            npyv_u32 ab2 = npyv_muladd_u32(a2, b2, ab3);
            npyv_u32 ab1 = npyv_muladd_u32(a1, b1, ab2);
                   v_accum = npyv_muladd_u32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u32 a0 = npyv_load_u32(data0 + vstep * 0);
            npyv_u32 b0 = npyv_load_u32(data1 + vstep * 0);
            
#line 501
            npyv_u32 a1 = npyv_load_u32(data0 + vstep * 1);
            npyv_u32 b1 = npyv_load_u32(data1 + vstep * 1);
            
#line 501
            npyv_u32 a2 = npyv_load_u32(data0 + vstep * 2);
            npyv_u32 b2 = npyv_load_u32(data1 + vstep * 2);
            
#line 501
            npyv_u32 a3 = npyv_load_u32(data0 + vstep * 3);
            npyv_u32 b3 = npyv_load_u32(data1 + vstep * 3);
            
            npyv_u32 ab3 = npyv_muladd_u32(a3, b3, v_accum);
            npyv_u32 ab2 = npyv_muladd_u32(a2, b2, ab3);
            npyv_u32 ab1 = npyv_muladd_u32(a1, b1, ab2);
                   v_accum = npyv_muladd_u32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u32 a = npyv_load_tillz_u32(data0, count);
        npyv_u32 b = npyv_load_tillz_u32(data1, count);
        v_accum = npyv_muladd_u32(a, b, v_accum);
    }
    accum = npyv_sum_u32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_uint ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_uint ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_uint ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_uint ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_uint a = (*data0);
        const npy_uint b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_uint
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint value0 = (*(npy_uint *)dataptr[0]);
    npy_uint accum = uint_sum_of_arr(data1, count);
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint value1 = (*(npy_uint *)dataptr[1]);
    npy_uint accum = uint_sum_of_arr(data0, count);
    *(npy_uint *)dataptr[2] = ((*(npy_uint *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
uint_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_uint *data0 = (npy_uint *)dataptr[0];
    npy_uint *data1 = (npy_uint *)dataptr[1];
    npy_uint *data2 = (npy_uint *)dataptr[2];
    npy_uint *data_out = (npy_uint *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
uint_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        *(npy_uint *)dataptr[nop] = (temp +
                                           (*(npy_uint *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_uint);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_uint *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[0];
        ((npy_uint *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_uint *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_uint);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
uint_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_uint *data = (npy_uint *)dataptr[0];
    npy_uint accum = uint_sum_of_arr(data, count);
    *((npy_uint *)dataptr[1]) = (accum + (*((npy_uint *)dataptr[1])));
#else
    npy_uint accum_re = 0, accum_im = 0;
    npy_uint *data0 = (npy_uint *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_uint re01 = data0[0] + data0[2];
        const npy_uint re23 = data0[4] + data0[6];
        const npy_uint im13 = data0[1] + data0[3];
        const npy_uint im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_uint *)dataptr[1])[0] += accum_re;
    ((npy_uint *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
uint_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_uint accum_re = 0, accum_im = 0;
#else
    npy_uint accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("uint_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_uint *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_uint *)data0) *
                 (*(npy_uint *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_uint *)data0) *
                 (*(npy_uint *)data1) *
                 (*(npy_uint *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_uint temp = (*(npy_uint *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_uint *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_uint *)data0)[0];
        accum_im += ((npy_uint *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_uint re, im, tmp;
        int i;
        re = ((npy_uint *)dataptr[0])[0];
        im = ((npy_uint *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_uint *)dataptr[i])[0] -
                  im * ((npy_uint *)dataptr[i])[1];
            im = re * ((npy_uint *)dataptr[i])[1] +
                 im * ((npy_uint *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_uint *)dataptr[1000])[0] += accum_re;
    ((npy_uint *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_uint *)dataptr[nop])[0] += accum_re;
    ((npy_uint *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_uint *)dataptr[1000]) = (accum +
                                    (*((npy_uint *)dataptr[1000])));
#  else
    *((npy_uint *)dataptr[nop]) = (accum +
                                    (*((npy_uint *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_ulong ulong_sum_of_arr(npy_ulong *data, npy_intp count)
{
    npy_ulong accum = 0;
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_ulong;
    npyv_ulong v_accum = npyv_zero_ulong();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_ulong a0 = npyv_loada_ulong(data + vstep * 0);
            
#line 96
            npyv_ulong a1 = npyv_loada_ulong(data + vstep * 1);
            
#line 96
            npyv_ulong a2 = npyv_loada_ulong(data + vstep * 2);
            
#line 96
            npyv_ulong a3 = npyv_loada_ulong(data + vstep * 3);
            
            npyv_ulong a01   = npyv_add_ulong(a0, a1);
            npyv_ulong a23   = npyv_add_ulong(a2, a3);
            npyv_ulong a0123 = npyv_add_ulong(a01, a23);
                     v_accum = npyv_add_ulong(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_ulong a0 = npyv_load_ulong(data + vstep * 0);
            
#line 96
            npyv_ulong a1 = npyv_load_ulong(data + vstep * 1);
            
#line 96
            npyv_ulong a2 = npyv_load_ulong(data + vstep * 2);
            
#line 96
            npyv_ulong a3 = npyv_load_ulong(data + vstep * 3);
            
            npyv_ulong a01   = npyv_add_ulong(a0, a1);
            npyv_ulong a23   = npyv_add_ulong(a2, a3);
            npyv_ulong a0123 = npyv_add_ulong(a01, a23);
                     v_accum = npyv_add_ulong(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data, count);
        v_accum = npyv_add_ulong(a, v_accum);
    }
    accum = npyv_sum_ulong(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_ulong a01 = (*data) + (data[1]);
        const npy_ulong a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_ulong
    return accum;
}
#endif

#line 131
static void
ulong_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) *
                                         (*(npy_ulong *)data1) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) *
                                         (*(npy_ulong *)data1) *
                                         (*(npy_ulong *)data2) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        *(npy_ulong *)dataptr[nop] = (temp +
                                           (*(npy_ulong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_ulong *)data_out)[0] = ((npy_ulong *)data0)[0] +
                                         ((npy_ulong *)data_out)[0];
        ((npy_ulong *)data_out)[1] = ((npy_ulong *)data0)[1] +
                                         ((npy_ulong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
ulong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data_out = (npy_ulong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ulong *)data_out + 2*6)[0] =
                                    ((npy_ulong *)data0 + 2*6)[0] +
                                    ((npy_ulong *)data_out + 2*6)[0];
            ((npy_ulong *)data_out + 2*6)[1] =
                                    ((npy_ulong *)data0 + 2*6)[1] +
                                    ((npy_ulong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ulong *)data_out + 2*5)[0] =
                                    ((npy_ulong *)data0 + 2*5)[0] +
                                    ((npy_ulong *)data_out + 2*5)[0];
            ((npy_ulong *)data_out + 2*5)[1] =
                                    ((npy_ulong *)data0 + 2*5)[1] +
                                    ((npy_ulong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ulong *)data_out + 2*4)[0] =
                                    ((npy_ulong *)data0 + 2*4)[0] +
                                    ((npy_ulong *)data_out + 2*4)[0];
            ((npy_ulong *)data_out + 2*4)[1] =
                                    ((npy_ulong *)data0 + 2*4)[1] +
                                    ((npy_ulong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ulong *)data_out + 2*3)[0] =
                                    ((npy_ulong *)data0 + 2*3)[0] +
                                    ((npy_ulong *)data_out + 2*3)[0];
            ((npy_ulong *)data_out + 2*3)[1] =
                                    ((npy_ulong *)data0 + 2*3)[1] +
                                    ((npy_ulong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ulong *)data_out + 2*2)[0] =
                                    ((npy_ulong *)data0 + 2*2)[0] +
                                    ((npy_ulong *)data_out + 2*2)[0];
            ((npy_ulong *)data_out + 2*2)[1] =
                                    ((npy_ulong *)data0 + 2*2)[1] +
                                    ((npy_ulong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ulong *)data_out + 2*1)[0] =
                                    ((npy_ulong *)data0 + 2*1)[0] +
                                    ((npy_ulong *)data_out + 2*1)[0];
            ((npy_ulong *)data_out + 2*1)[1] =
                                    ((npy_ulong *)data0 + 2*1)[1] +
                                    ((npy_ulong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ulong *)data_out + 2*0)[0] =
                                    ((npy_ulong *)data0 + 2*0)[0] +
                                    ((npy_ulong *)data_out + 2*0)[0];
            ((npy_ulong *)data_out + 2*0)[1] =
                                    ((npy_ulong *)data0 + 2*0)[1] +
                                    ((npy_ulong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ulong *)data_out + 2*0)[0] =
                                ((npy_ulong *)data0 + 2*0)[0] +
                                ((npy_ulong *)data_out + 2*0)[0];
        ((npy_ulong *)data_out + 2*0)[1] =
                                ((npy_ulong *)data0 + 2*0)[1] +
                                ((npy_ulong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ulong *)data_out + 2*1)[0] =
                                ((npy_ulong *)data0 + 2*1)[0] +
                                ((npy_ulong *)data_out + 2*1)[0];
        ((npy_ulong *)data_out + 2*1)[1] =
                                ((npy_ulong *)data0 + 2*1)[1] +
                                ((npy_ulong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ulong *)data_out + 2*2)[0] =
                                ((npy_ulong *)data0 + 2*2)[0] +
                                ((npy_ulong *)data_out + 2*2)[0];
        ((npy_ulong *)data_out + 2*2)[1] =
                                ((npy_ulong *)data0 + 2*2)[1] +
                                ((npy_ulong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ulong *)data_out + 2*3)[0] =
                                ((npy_ulong *)data0 + 2*3)[0] +
                                ((npy_ulong *)data_out + 2*3)[0];
        ((npy_ulong *)data_out + 2*3)[1] =
                                ((npy_ulong *)data0 + 2*3)[1] +
                                ((npy_ulong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ulong *)data_out + 2*4)[0] =
                                ((npy_ulong *)data0 + 2*4)[0] +
                                ((npy_ulong *)data_out + 2*4)[0];
        ((npy_ulong *)data_out + 2*4)[1] =
                                ((npy_ulong *)data0 + 2*4)[1] +
                                ((npy_ulong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ulong *)data_out + 2*5)[0] =
                                ((npy_ulong *)data0 + 2*5)[0] +
                                ((npy_ulong *)data_out + 2*5)[0];
        ((npy_ulong *)data_out + 2*5)[1] =
                                ((npy_ulong *)data0 + 2*5)[1] +
                                ((npy_ulong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ulong *)data_out + 2*6)[0] =
                                ((npy_ulong *)data0 + 2*6)[0] +
                                ((npy_ulong *)data_out + 2*6)[0];
        ((npy_ulong *)data_out + 2*6)[1] =
                                ((npy_ulong *)data0 + 2*6)[1] +
                                ((npy_ulong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ulong *)data_out + 2*7)[0] =
                                ((npy_ulong *)data0 + 2*7)[0] +
                                ((npy_ulong *)data_out + 2*7)[0];
        ((npy_ulong *)data_out + 2*7)[1] =
                                ((npy_ulong *)data0 + 2*7)[1] +
                                ((npy_ulong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ulong_sum_of_products_muladd(npy_ulong *data, npy_ulong *data_out, npy_ulong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_ulong;
    const npyv_ulong v_scalar = npyv_setall_ulong(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_ulong b0 = npyv_loada_ulong(data + vstep * 0);
            npyv_ulong c0 = npyv_loada_ulong(data_out + vstep * 0);
            
#line 312
            npyv_ulong b1 = npyv_loada_ulong(data + vstep * 1);
            npyv_ulong c1 = npyv_loada_ulong(data_out + vstep * 1);
            
#line 312
            npyv_ulong b2 = npyv_loada_ulong(data + vstep * 2);
            npyv_ulong c2 = npyv_loada_ulong(data_out + vstep * 2);
            
#line 312
            npyv_ulong b3 = npyv_loada_ulong(data + vstep * 3);
            npyv_ulong c3 = npyv_loada_ulong(data_out + vstep * 3);
            
            #line 318
            npyv_ulong abc0 = npyv_muladd_ulong(v_scalar, b0, c0);
            
#line 318
            npyv_ulong abc1 = npyv_muladd_ulong(v_scalar, b1, c1);
            
#line 318
            npyv_ulong abc2 = npyv_muladd_ulong(v_scalar, b2, c2);
            
#line 318
            npyv_ulong abc3 = npyv_muladd_ulong(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_ulong(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_ulong b0 = npyv_load_ulong(data + vstep * 0);
            npyv_ulong c0 = npyv_load_ulong(data_out + vstep * 0);
            
#line 312
            npyv_ulong b1 = npyv_load_ulong(data + vstep * 1);
            npyv_ulong c1 = npyv_load_ulong(data_out + vstep * 1);
            
#line 312
            npyv_ulong b2 = npyv_load_ulong(data + vstep * 2);
            npyv_ulong c2 = npyv_load_ulong(data_out + vstep * 2);
            
#line 312
            npyv_ulong b3 = npyv_load_ulong(data + vstep * 3);
            npyv_ulong c3 = npyv_load_ulong(data_out + vstep * 3);
            
            #line 318
            npyv_ulong abc0 = npyv_muladd_ulong(v_scalar, b0, c0);
            
#line 318
            npyv_ulong abc1 = npyv_muladd_ulong(v_scalar, b1, c1);
            
#line 318
            npyv_ulong abc2 = npyv_muladd_ulong(v_scalar, b2, c2);
            
#line 318
            npyv_ulong abc3 = npyv_muladd_ulong(v_scalar, b3, c3);
            
            #line 323
            npyv_store_ulong(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_ulong(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_ulong(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data, count);
        npyv_ulong b = npyv_load_tillz_ulong(data_out, count);
        npyv_store_till_ulong(data_out, count, npyv_muladd_ulong(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ulong b0 = (data[0]);
        const npy_ulong c0 = (data_out[0]);
        
#line 340
        const npy_ulong b1 = (data[1]);
        const npy_ulong c1 = (data_out[1]);
        
#line 340
        const npy_ulong b2 = (data[2]);
        const npy_ulong c2 = (data_out[2]);
        
#line 340
        const npy_ulong b3 = (data[3]);
        const npy_ulong c3 = (data_out[3]);
        
        #line 346
        const npy_ulong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ulong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ulong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ulong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ulong b = (*data);
        const npy_ulong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ulong
}

static void
ulong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ulong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_ulong;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_ulong a0 = npyv_loada_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_loada_ulong(data1 + vstep * 0);
            npyv_ulong c0 = npyv_loada_ulong(data_out + vstep * 0);
            
#line 390
            npyv_ulong a1 = npyv_loada_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_loada_ulong(data1 + vstep * 1);
            npyv_ulong c1 = npyv_loada_ulong(data_out + vstep * 1);
            
#line 390
            npyv_ulong a2 = npyv_loada_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_loada_ulong(data1 + vstep * 2);
            npyv_ulong c2 = npyv_loada_ulong(data_out + vstep * 2);
            
#line 390
            npyv_ulong a3 = npyv_loada_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_loada_ulong(data1 + vstep * 3);
            npyv_ulong c3 = npyv_loada_ulong(data_out + vstep * 3);
            
            #line 397
            npyv_ulong abc0 = npyv_muladd_ulong(a0, b0, c0);
            
#line 397
            npyv_ulong abc1 = npyv_muladd_ulong(a1, b1, c1);
            
#line 397
            npyv_ulong abc2 = npyv_muladd_ulong(a2, b2, c2);
            
#line 397
            npyv_ulong abc3 = npyv_muladd_ulong(a3, b3, c3);
            
            #line 402
            npyv_storea_ulong(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_ulong a0 = npyv_load_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_load_ulong(data1 + vstep * 0);
            npyv_ulong c0 = npyv_load_ulong(data_out + vstep * 0);
            
#line 390
            npyv_ulong a1 = npyv_load_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_load_ulong(data1 + vstep * 1);
            npyv_ulong c1 = npyv_load_ulong(data_out + vstep * 1);
            
#line 390
            npyv_ulong a2 = npyv_load_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_load_ulong(data1 + vstep * 2);
            npyv_ulong c2 = npyv_load_ulong(data_out + vstep * 2);
            
#line 390
            npyv_ulong a3 = npyv_load_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_load_ulong(data1 + vstep * 3);
            npyv_ulong c3 = npyv_load_ulong(data_out + vstep * 3);
            
            #line 397
            npyv_ulong abc0 = npyv_muladd_ulong(a0, b0, c0);
            
#line 397
            npyv_ulong abc1 = npyv_muladd_ulong(a1, b1, c1);
            
#line 397
            npyv_ulong abc2 = npyv_muladd_ulong(a2, b2, c2);
            
#line 397
            npyv_ulong abc3 = npyv_muladd_ulong(a3, b3, c3);
            
            #line 402
            npyv_store_ulong(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_ulong(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_ulong(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data0, count);
        npyv_ulong b = npyv_load_tillz_ulong(data1, count);
        npyv_ulong c = npyv_load_tillz_ulong(data_out, count);
        npyv_store_till_ulong(data_out, count, npyv_muladd_ulong(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ulong a0 = (data0[0]);
        const npy_ulong b0 = (data1[0]);
        const npy_ulong c0 = (data_out[0]);
        
#line 420
        const npy_ulong a1 = (data0[1]);
        const npy_ulong b1 = (data1[1]);
        const npy_ulong c1 = (data_out[1]);
        
#line 420
        const npy_ulong a2 = (data0[2]);
        const npy_ulong b2 = (data1[2]);
        const npy_ulong c2 = (data_out[2]);
        
#line 420
        const npy_ulong a3 = (data0[3]);
        const npy_ulong b3 = (data1[3]);
        const npy_ulong c3 = (data_out[3]);
        
        #line 427
        const npy_ulong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ulong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ulong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ulong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ulong a = (*data0);
        const npy_ulong b = (*data1);
        const npy_ulong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ulong

}

/* Some extra specializations for the two operand case */
static void
ulong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong value0 = (*(npy_ulong *)dataptr[0]);
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ulong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ulong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong value1 = (*(npy_ulong *)dataptr[1]);
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ulong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong accum = 0;

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_ulong;
    npyv_ulong v_accum = npyv_zero_ulong();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_ulong a0 = npyv_loada_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_loada_ulong(data1 + vstep * 0);
            
#line 501
            npyv_ulong a1 = npyv_loada_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_loada_ulong(data1 + vstep * 1);
            
#line 501
            npyv_ulong a2 = npyv_loada_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_loada_ulong(data1 + vstep * 2);
            
#line 501
            npyv_ulong a3 = npyv_loada_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_loada_ulong(data1 + vstep * 3);
            
            npyv_ulong ab3 = npyv_muladd_ulong(a3, b3, v_accum);
            npyv_ulong ab2 = npyv_muladd_ulong(a2, b2, ab3);
            npyv_ulong ab1 = npyv_muladd_ulong(a1, b1, ab2);
                   v_accum = npyv_muladd_ulong(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_ulong a0 = npyv_load_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_load_ulong(data1 + vstep * 0);
            
#line 501
            npyv_ulong a1 = npyv_load_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_load_ulong(data1 + vstep * 1);
            
#line 501
            npyv_ulong a2 = npyv_load_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_load_ulong(data1 + vstep * 2);
            
#line 501
            npyv_ulong a3 = npyv_load_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_load_ulong(data1 + vstep * 3);
            
            npyv_ulong ab3 = npyv_muladd_ulong(a3, b3, v_accum);
            npyv_ulong ab2 = npyv_muladd_ulong(a2, b2, ab3);
            npyv_ulong ab1 = npyv_muladd_ulong(a1, b1, ab2);
                   v_accum = npyv_muladd_ulong(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data0, count);
        npyv_ulong b = npyv_load_tillz_ulong(data1, count);
        v_accum = npyv_muladd_ulong(a, b, v_accum);
    }
    accum = npyv_sum_ulong(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ulong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ulong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ulong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ulong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ulong a = (*data0);
        const npy_ulong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ulong
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong value0 = (*(npy_ulong *)dataptr[0]);
    npy_ulong accum = ulong_sum_of_arr(data1, count);
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong value1 = (*(npy_ulong *)dataptr[1]);
    npy_ulong accum = ulong_sum_of_arr(data0, count);
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
ulong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data2 = (npy_ulong *)dataptr[2];
    npy_ulong *data_out = (npy_ulong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
ulong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        *(npy_ulong *)dataptr[nop] = (temp +
                                           (*(npy_ulong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ulong);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ulong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ulong *data = (npy_ulong *)dataptr[0];
    npy_ulong accum = ulong_sum_of_arr(data, count);
    *((npy_ulong *)dataptr[1]) = (accum + (*((npy_ulong *)dataptr[1])));
#else
    npy_ulong accum_re = 0, accum_im = 0;
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ulong re01 = data0[0] + data0[2];
        const npy_ulong re23 = data0[4] + data0[6];
        const npy_ulong im13 = data0[1] + data0[3];
        const npy_ulong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ulong *)dataptr[1])[0] += accum_re;
    ((npy_ulong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
ulong_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ulong accum_re = 0, accum_im = 0;
#else
    npy_ulong accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_ulong *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_ulong *)data0) *
                 (*(npy_ulong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_ulong *)data0) *
                 (*(npy_ulong *)data1) *
                 (*(npy_ulong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_ulong *)data0)[0];
        accum_im += ((npy_ulong *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_ulong *)dataptr[1])[0] += accum_re;
    ((npy_ulong *)dataptr[1])[1] += accum_im;
#  else
    ((npy_ulong *)dataptr[nop])[0] += accum_re;
    ((npy_ulong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_ulong *)dataptr[1]) = (accum +
                                    (*((npy_ulong *)dataptr[1])));
#  else
    *((npy_ulong *)dataptr[nop]) = (accum +
                                    (*((npy_ulong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ulong_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) *
                                         (*(npy_ulong *)data1) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) *
                                         (*(npy_ulong *)data1) *
                                         (*(npy_ulong *)data2) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        *(npy_ulong *)dataptr[nop] = (temp +
                                           (*(npy_ulong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_ulong *)data_out)[0] = ((npy_ulong *)data0)[0] +
                                         ((npy_ulong *)data_out)[0];
        ((npy_ulong *)data_out)[1] = ((npy_ulong *)data0)[1] +
                                         ((npy_ulong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
ulong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data_out = (npy_ulong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ulong *)data_out + 2*6)[0] =
                                    ((npy_ulong *)data0 + 2*6)[0] +
                                    ((npy_ulong *)data_out + 2*6)[0];
            ((npy_ulong *)data_out + 2*6)[1] =
                                    ((npy_ulong *)data0 + 2*6)[1] +
                                    ((npy_ulong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ulong *)data_out + 2*5)[0] =
                                    ((npy_ulong *)data0 + 2*5)[0] +
                                    ((npy_ulong *)data_out + 2*5)[0];
            ((npy_ulong *)data_out + 2*5)[1] =
                                    ((npy_ulong *)data0 + 2*5)[1] +
                                    ((npy_ulong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ulong *)data_out + 2*4)[0] =
                                    ((npy_ulong *)data0 + 2*4)[0] +
                                    ((npy_ulong *)data_out + 2*4)[0];
            ((npy_ulong *)data_out + 2*4)[1] =
                                    ((npy_ulong *)data0 + 2*4)[1] +
                                    ((npy_ulong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ulong *)data_out + 2*3)[0] =
                                    ((npy_ulong *)data0 + 2*3)[0] +
                                    ((npy_ulong *)data_out + 2*3)[0];
            ((npy_ulong *)data_out + 2*3)[1] =
                                    ((npy_ulong *)data0 + 2*3)[1] +
                                    ((npy_ulong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ulong *)data_out + 2*2)[0] =
                                    ((npy_ulong *)data0 + 2*2)[0] +
                                    ((npy_ulong *)data_out + 2*2)[0];
            ((npy_ulong *)data_out + 2*2)[1] =
                                    ((npy_ulong *)data0 + 2*2)[1] +
                                    ((npy_ulong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ulong *)data_out + 2*1)[0] =
                                    ((npy_ulong *)data0 + 2*1)[0] +
                                    ((npy_ulong *)data_out + 2*1)[0];
            ((npy_ulong *)data_out + 2*1)[1] =
                                    ((npy_ulong *)data0 + 2*1)[1] +
                                    ((npy_ulong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ulong *)data_out + 2*0)[0] =
                                    ((npy_ulong *)data0 + 2*0)[0] +
                                    ((npy_ulong *)data_out + 2*0)[0];
            ((npy_ulong *)data_out + 2*0)[1] =
                                    ((npy_ulong *)data0 + 2*0)[1] +
                                    ((npy_ulong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ulong *)data_out + 2*0)[0] =
                                ((npy_ulong *)data0 + 2*0)[0] +
                                ((npy_ulong *)data_out + 2*0)[0];
        ((npy_ulong *)data_out + 2*0)[1] =
                                ((npy_ulong *)data0 + 2*0)[1] +
                                ((npy_ulong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ulong *)data_out + 2*1)[0] =
                                ((npy_ulong *)data0 + 2*1)[0] +
                                ((npy_ulong *)data_out + 2*1)[0];
        ((npy_ulong *)data_out + 2*1)[1] =
                                ((npy_ulong *)data0 + 2*1)[1] +
                                ((npy_ulong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ulong *)data_out + 2*2)[0] =
                                ((npy_ulong *)data0 + 2*2)[0] +
                                ((npy_ulong *)data_out + 2*2)[0];
        ((npy_ulong *)data_out + 2*2)[1] =
                                ((npy_ulong *)data0 + 2*2)[1] +
                                ((npy_ulong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ulong *)data_out + 2*3)[0] =
                                ((npy_ulong *)data0 + 2*3)[0] +
                                ((npy_ulong *)data_out + 2*3)[0];
        ((npy_ulong *)data_out + 2*3)[1] =
                                ((npy_ulong *)data0 + 2*3)[1] +
                                ((npy_ulong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ulong *)data_out + 2*4)[0] =
                                ((npy_ulong *)data0 + 2*4)[0] +
                                ((npy_ulong *)data_out + 2*4)[0];
        ((npy_ulong *)data_out + 2*4)[1] =
                                ((npy_ulong *)data0 + 2*4)[1] +
                                ((npy_ulong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ulong *)data_out + 2*5)[0] =
                                ((npy_ulong *)data0 + 2*5)[0] +
                                ((npy_ulong *)data_out + 2*5)[0];
        ((npy_ulong *)data_out + 2*5)[1] =
                                ((npy_ulong *)data0 + 2*5)[1] +
                                ((npy_ulong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ulong *)data_out + 2*6)[0] =
                                ((npy_ulong *)data0 + 2*6)[0] +
                                ((npy_ulong *)data_out + 2*6)[0];
        ((npy_ulong *)data_out + 2*6)[1] =
                                ((npy_ulong *)data0 + 2*6)[1] +
                                ((npy_ulong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ulong *)data_out + 2*7)[0] =
                                ((npy_ulong *)data0 + 2*7)[0] +
                                ((npy_ulong *)data_out + 2*7)[0];
        ((npy_ulong *)data_out + 2*7)[1] =
                                ((npy_ulong *)data0 + 2*7)[1] +
                                ((npy_ulong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ulong_sum_of_products_muladd(npy_ulong *data, npy_ulong *data_out, npy_ulong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_ulong;
    const npyv_ulong v_scalar = npyv_setall_ulong(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_ulong b0 = npyv_loada_ulong(data + vstep * 0);
            npyv_ulong c0 = npyv_loada_ulong(data_out + vstep * 0);
            
#line 312
            npyv_ulong b1 = npyv_loada_ulong(data + vstep * 1);
            npyv_ulong c1 = npyv_loada_ulong(data_out + vstep * 1);
            
#line 312
            npyv_ulong b2 = npyv_loada_ulong(data + vstep * 2);
            npyv_ulong c2 = npyv_loada_ulong(data_out + vstep * 2);
            
#line 312
            npyv_ulong b3 = npyv_loada_ulong(data + vstep * 3);
            npyv_ulong c3 = npyv_loada_ulong(data_out + vstep * 3);
            
            #line 318
            npyv_ulong abc0 = npyv_muladd_ulong(v_scalar, b0, c0);
            
#line 318
            npyv_ulong abc1 = npyv_muladd_ulong(v_scalar, b1, c1);
            
#line 318
            npyv_ulong abc2 = npyv_muladd_ulong(v_scalar, b2, c2);
            
#line 318
            npyv_ulong abc3 = npyv_muladd_ulong(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_ulong(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_ulong b0 = npyv_load_ulong(data + vstep * 0);
            npyv_ulong c0 = npyv_load_ulong(data_out + vstep * 0);
            
#line 312
            npyv_ulong b1 = npyv_load_ulong(data + vstep * 1);
            npyv_ulong c1 = npyv_load_ulong(data_out + vstep * 1);
            
#line 312
            npyv_ulong b2 = npyv_load_ulong(data + vstep * 2);
            npyv_ulong c2 = npyv_load_ulong(data_out + vstep * 2);
            
#line 312
            npyv_ulong b3 = npyv_load_ulong(data + vstep * 3);
            npyv_ulong c3 = npyv_load_ulong(data_out + vstep * 3);
            
            #line 318
            npyv_ulong abc0 = npyv_muladd_ulong(v_scalar, b0, c0);
            
#line 318
            npyv_ulong abc1 = npyv_muladd_ulong(v_scalar, b1, c1);
            
#line 318
            npyv_ulong abc2 = npyv_muladd_ulong(v_scalar, b2, c2);
            
#line 318
            npyv_ulong abc3 = npyv_muladd_ulong(v_scalar, b3, c3);
            
            #line 323
            npyv_store_ulong(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_ulong(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_ulong(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data, count);
        npyv_ulong b = npyv_load_tillz_ulong(data_out, count);
        npyv_store_till_ulong(data_out, count, npyv_muladd_ulong(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ulong b0 = (data[0]);
        const npy_ulong c0 = (data_out[0]);
        
#line 340
        const npy_ulong b1 = (data[1]);
        const npy_ulong c1 = (data_out[1]);
        
#line 340
        const npy_ulong b2 = (data[2]);
        const npy_ulong c2 = (data_out[2]);
        
#line 340
        const npy_ulong b3 = (data[3]);
        const npy_ulong c3 = (data_out[3]);
        
        #line 346
        const npy_ulong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ulong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ulong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ulong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ulong b = (*data);
        const npy_ulong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ulong
}

static void
ulong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ulong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_ulong;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_ulong a0 = npyv_loada_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_loada_ulong(data1 + vstep * 0);
            npyv_ulong c0 = npyv_loada_ulong(data_out + vstep * 0);
            
#line 390
            npyv_ulong a1 = npyv_loada_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_loada_ulong(data1 + vstep * 1);
            npyv_ulong c1 = npyv_loada_ulong(data_out + vstep * 1);
            
#line 390
            npyv_ulong a2 = npyv_loada_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_loada_ulong(data1 + vstep * 2);
            npyv_ulong c2 = npyv_loada_ulong(data_out + vstep * 2);
            
#line 390
            npyv_ulong a3 = npyv_loada_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_loada_ulong(data1 + vstep * 3);
            npyv_ulong c3 = npyv_loada_ulong(data_out + vstep * 3);
            
            #line 397
            npyv_ulong abc0 = npyv_muladd_ulong(a0, b0, c0);
            
#line 397
            npyv_ulong abc1 = npyv_muladd_ulong(a1, b1, c1);
            
#line 397
            npyv_ulong abc2 = npyv_muladd_ulong(a2, b2, c2);
            
#line 397
            npyv_ulong abc3 = npyv_muladd_ulong(a3, b3, c3);
            
            #line 402
            npyv_storea_ulong(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_ulong a0 = npyv_load_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_load_ulong(data1 + vstep * 0);
            npyv_ulong c0 = npyv_load_ulong(data_out + vstep * 0);
            
#line 390
            npyv_ulong a1 = npyv_load_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_load_ulong(data1 + vstep * 1);
            npyv_ulong c1 = npyv_load_ulong(data_out + vstep * 1);
            
#line 390
            npyv_ulong a2 = npyv_load_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_load_ulong(data1 + vstep * 2);
            npyv_ulong c2 = npyv_load_ulong(data_out + vstep * 2);
            
#line 390
            npyv_ulong a3 = npyv_load_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_load_ulong(data1 + vstep * 3);
            npyv_ulong c3 = npyv_load_ulong(data_out + vstep * 3);
            
            #line 397
            npyv_ulong abc0 = npyv_muladd_ulong(a0, b0, c0);
            
#line 397
            npyv_ulong abc1 = npyv_muladd_ulong(a1, b1, c1);
            
#line 397
            npyv_ulong abc2 = npyv_muladd_ulong(a2, b2, c2);
            
#line 397
            npyv_ulong abc3 = npyv_muladd_ulong(a3, b3, c3);
            
            #line 402
            npyv_store_ulong(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_ulong(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_ulong(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data0, count);
        npyv_ulong b = npyv_load_tillz_ulong(data1, count);
        npyv_ulong c = npyv_load_tillz_ulong(data_out, count);
        npyv_store_till_ulong(data_out, count, npyv_muladd_ulong(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ulong a0 = (data0[0]);
        const npy_ulong b0 = (data1[0]);
        const npy_ulong c0 = (data_out[0]);
        
#line 420
        const npy_ulong a1 = (data0[1]);
        const npy_ulong b1 = (data1[1]);
        const npy_ulong c1 = (data_out[1]);
        
#line 420
        const npy_ulong a2 = (data0[2]);
        const npy_ulong b2 = (data1[2]);
        const npy_ulong c2 = (data_out[2]);
        
#line 420
        const npy_ulong a3 = (data0[3]);
        const npy_ulong b3 = (data1[3]);
        const npy_ulong c3 = (data_out[3]);
        
        #line 427
        const npy_ulong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ulong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ulong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ulong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ulong a = (*data0);
        const npy_ulong b = (*data1);
        const npy_ulong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ulong

}

/* Some extra specializations for the two operand case */
static void
ulong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong value0 = (*(npy_ulong *)dataptr[0]);
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ulong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ulong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong value1 = (*(npy_ulong *)dataptr[1]);
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ulong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong accum = 0;

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_ulong;
    npyv_ulong v_accum = npyv_zero_ulong();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_ulong a0 = npyv_loada_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_loada_ulong(data1 + vstep * 0);
            
#line 501
            npyv_ulong a1 = npyv_loada_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_loada_ulong(data1 + vstep * 1);
            
#line 501
            npyv_ulong a2 = npyv_loada_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_loada_ulong(data1 + vstep * 2);
            
#line 501
            npyv_ulong a3 = npyv_loada_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_loada_ulong(data1 + vstep * 3);
            
            npyv_ulong ab3 = npyv_muladd_ulong(a3, b3, v_accum);
            npyv_ulong ab2 = npyv_muladd_ulong(a2, b2, ab3);
            npyv_ulong ab1 = npyv_muladd_ulong(a1, b1, ab2);
                   v_accum = npyv_muladd_ulong(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_ulong a0 = npyv_load_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_load_ulong(data1 + vstep * 0);
            
#line 501
            npyv_ulong a1 = npyv_load_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_load_ulong(data1 + vstep * 1);
            
#line 501
            npyv_ulong a2 = npyv_load_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_load_ulong(data1 + vstep * 2);
            
#line 501
            npyv_ulong a3 = npyv_load_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_load_ulong(data1 + vstep * 3);
            
            npyv_ulong ab3 = npyv_muladd_ulong(a3, b3, v_accum);
            npyv_ulong ab2 = npyv_muladd_ulong(a2, b2, ab3);
            npyv_ulong ab1 = npyv_muladd_ulong(a1, b1, ab2);
                   v_accum = npyv_muladd_ulong(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data0, count);
        npyv_ulong b = npyv_load_tillz_ulong(data1, count);
        v_accum = npyv_muladd_ulong(a, b, v_accum);
    }
    accum = npyv_sum_ulong(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ulong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ulong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ulong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ulong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ulong a = (*data0);
        const npy_ulong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ulong
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong value0 = (*(npy_ulong *)dataptr[0]);
    npy_ulong accum = ulong_sum_of_arr(data1, count);
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong value1 = (*(npy_ulong *)dataptr[1]);
    npy_ulong accum = ulong_sum_of_arr(data0, count);
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
ulong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data2 = (npy_ulong *)dataptr[2];
    npy_ulong *data_out = (npy_ulong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
ulong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        *(npy_ulong *)dataptr[nop] = (temp +
                                           (*(npy_ulong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ulong);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ulong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ulong *data = (npy_ulong *)dataptr[0];
    npy_ulong accum = ulong_sum_of_arr(data, count);
    *((npy_ulong *)dataptr[1]) = (accum + (*((npy_ulong *)dataptr[1])));
#else
    npy_ulong accum_re = 0, accum_im = 0;
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ulong re01 = data0[0] + data0[2];
        const npy_ulong re23 = data0[4] + data0[6];
        const npy_ulong im13 = data0[1] + data0[3];
        const npy_ulong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ulong *)dataptr[1])[0] += accum_re;
    ((npy_ulong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
ulong_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ulong accum_re = 0, accum_im = 0;
#else
    npy_ulong accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_ulong *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_ulong *)data0) *
                 (*(npy_ulong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_ulong *)data0) *
                 (*(npy_ulong *)data1) *
                 (*(npy_ulong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_ulong *)data0)[0];
        accum_im += ((npy_ulong *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_ulong *)dataptr[2])[0] += accum_re;
    ((npy_ulong *)dataptr[2])[1] += accum_im;
#  else
    ((npy_ulong *)dataptr[nop])[0] += accum_re;
    ((npy_ulong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_ulong *)dataptr[2]) = (accum +
                                    (*((npy_ulong *)dataptr[2])));
#  else
    *((npy_ulong *)dataptr[nop]) = (accum +
                                    (*((npy_ulong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ulong_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) *
                                         (*(npy_ulong *)data1) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) *
                                         (*(npy_ulong *)data1) *
                                         (*(npy_ulong *)data2) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        *(npy_ulong *)dataptr[nop] = (temp +
                                           (*(npy_ulong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_ulong *)data_out)[0] = ((npy_ulong *)data0)[0] +
                                         ((npy_ulong *)data_out)[0];
        ((npy_ulong *)data_out)[1] = ((npy_ulong *)data0)[1] +
                                         ((npy_ulong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
ulong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data_out = (npy_ulong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ulong *)data_out + 2*6)[0] =
                                    ((npy_ulong *)data0 + 2*6)[0] +
                                    ((npy_ulong *)data_out + 2*6)[0];
            ((npy_ulong *)data_out + 2*6)[1] =
                                    ((npy_ulong *)data0 + 2*6)[1] +
                                    ((npy_ulong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ulong *)data_out + 2*5)[0] =
                                    ((npy_ulong *)data0 + 2*5)[0] +
                                    ((npy_ulong *)data_out + 2*5)[0];
            ((npy_ulong *)data_out + 2*5)[1] =
                                    ((npy_ulong *)data0 + 2*5)[1] +
                                    ((npy_ulong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ulong *)data_out + 2*4)[0] =
                                    ((npy_ulong *)data0 + 2*4)[0] +
                                    ((npy_ulong *)data_out + 2*4)[0];
            ((npy_ulong *)data_out + 2*4)[1] =
                                    ((npy_ulong *)data0 + 2*4)[1] +
                                    ((npy_ulong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ulong *)data_out + 2*3)[0] =
                                    ((npy_ulong *)data0 + 2*3)[0] +
                                    ((npy_ulong *)data_out + 2*3)[0];
            ((npy_ulong *)data_out + 2*3)[1] =
                                    ((npy_ulong *)data0 + 2*3)[1] +
                                    ((npy_ulong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ulong *)data_out + 2*2)[0] =
                                    ((npy_ulong *)data0 + 2*2)[0] +
                                    ((npy_ulong *)data_out + 2*2)[0];
            ((npy_ulong *)data_out + 2*2)[1] =
                                    ((npy_ulong *)data0 + 2*2)[1] +
                                    ((npy_ulong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ulong *)data_out + 2*1)[0] =
                                    ((npy_ulong *)data0 + 2*1)[0] +
                                    ((npy_ulong *)data_out + 2*1)[0];
            ((npy_ulong *)data_out + 2*1)[1] =
                                    ((npy_ulong *)data0 + 2*1)[1] +
                                    ((npy_ulong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ulong *)data_out + 2*0)[0] =
                                    ((npy_ulong *)data0 + 2*0)[0] +
                                    ((npy_ulong *)data_out + 2*0)[0];
            ((npy_ulong *)data_out + 2*0)[1] =
                                    ((npy_ulong *)data0 + 2*0)[1] +
                                    ((npy_ulong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ulong *)data_out + 2*0)[0] =
                                ((npy_ulong *)data0 + 2*0)[0] +
                                ((npy_ulong *)data_out + 2*0)[0];
        ((npy_ulong *)data_out + 2*0)[1] =
                                ((npy_ulong *)data0 + 2*0)[1] +
                                ((npy_ulong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ulong *)data_out + 2*1)[0] =
                                ((npy_ulong *)data0 + 2*1)[0] +
                                ((npy_ulong *)data_out + 2*1)[0];
        ((npy_ulong *)data_out + 2*1)[1] =
                                ((npy_ulong *)data0 + 2*1)[1] +
                                ((npy_ulong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ulong *)data_out + 2*2)[0] =
                                ((npy_ulong *)data0 + 2*2)[0] +
                                ((npy_ulong *)data_out + 2*2)[0];
        ((npy_ulong *)data_out + 2*2)[1] =
                                ((npy_ulong *)data0 + 2*2)[1] +
                                ((npy_ulong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ulong *)data_out + 2*3)[0] =
                                ((npy_ulong *)data0 + 2*3)[0] +
                                ((npy_ulong *)data_out + 2*3)[0];
        ((npy_ulong *)data_out + 2*3)[1] =
                                ((npy_ulong *)data0 + 2*3)[1] +
                                ((npy_ulong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ulong *)data_out + 2*4)[0] =
                                ((npy_ulong *)data0 + 2*4)[0] +
                                ((npy_ulong *)data_out + 2*4)[0];
        ((npy_ulong *)data_out + 2*4)[1] =
                                ((npy_ulong *)data0 + 2*4)[1] +
                                ((npy_ulong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ulong *)data_out + 2*5)[0] =
                                ((npy_ulong *)data0 + 2*5)[0] +
                                ((npy_ulong *)data_out + 2*5)[0];
        ((npy_ulong *)data_out + 2*5)[1] =
                                ((npy_ulong *)data0 + 2*5)[1] +
                                ((npy_ulong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ulong *)data_out + 2*6)[0] =
                                ((npy_ulong *)data0 + 2*6)[0] +
                                ((npy_ulong *)data_out + 2*6)[0];
        ((npy_ulong *)data_out + 2*6)[1] =
                                ((npy_ulong *)data0 + 2*6)[1] +
                                ((npy_ulong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ulong *)data_out + 2*7)[0] =
                                ((npy_ulong *)data0 + 2*7)[0] +
                                ((npy_ulong *)data_out + 2*7)[0];
        ((npy_ulong *)data_out + 2*7)[1] =
                                ((npy_ulong *)data0 + 2*7)[1] +
                                ((npy_ulong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ulong_sum_of_products_muladd(npy_ulong *data, npy_ulong *data_out, npy_ulong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_ulong;
    const npyv_ulong v_scalar = npyv_setall_ulong(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_ulong b0 = npyv_loada_ulong(data + vstep * 0);
            npyv_ulong c0 = npyv_loada_ulong(data_out + vstep * 0);
            
#line 312
            npyv_ulong b1 = npyv_loada_ulong(data + vstep * 1);
            npyv_ulong c1 = npyv_loada_ulong(data_out + vstep * 1);
            
#line 312
            npyv_ulong b2 = npyv_loada_ulong(data + vstep * 2);
            npyv_ulong c2 = npyv_loada_ulong(data_out + vstep * 2);
            
#line 312
            npyv_ulong b3 = npyv_loada_ulong(data + vstep * 3);
            npyv_ulong c3 = npyv_loada_ulong(data_out + vstep * 3);
            
            #line 318
            npyv_ulong abc0 = npyv_muladd_ulong(v_scalar, b0, c0);
            
#line 318
            npyv_ulong abc1 = npyv_muladd_ulong(v_scalar, b1, c1);
            
#line 318
            npyv_ulong abc2 = npyv_muladd_ulong(v_scalar, b2, c2);
            
#line 318
            npyv_ulong abc3 = npyv_muladd_ulong(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_ulong(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_ulong b0 = npyv_load_ulong(data + vstep * 0);
            npyv_ulong c0 = npyv_load_ulong(data_out + vstep * 0);
            
#line 312
            npyv_ulong b1 = npyv_load_ulong(data + vstep * 1);
            npyv_ulong c1 = npyv_load_ulong(data_out + vstep * 1);
            
#line 312
            npyv_ulong b2 = npyv_load_ulong(data + vstep * 2);
            npyv_ulong c2 = npyv_load_ulong(data_out + vstep * 2);
            
#line 312
            npyv_ulong b3 = npyv_load_ulong(data + vstep * 3);
            npyv_ulong c3 = npyv_load_ulong(data_out + vstep * 3);
            
            #line 318
            npyv_ulong abc0 = npyv_muladd_ulong(v_scalar, b0, c0);
            
#line 318
            npyv_ulong abc1 = npyv_muladd_ulong(v_scalar, b1, c1);
            
#line 318
            npyv_ulong abc2 = npyv_muladd_ulong(v_scalar, b2, c2);
            
#line 318
            npyv_ulong abc3 = npyv_muladd_ulong(v_scalar, b3, c3);
            
            #line 323
            npyv_store_ulong(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_ulong(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_ulong(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data, count);
        npyv_ulong b = npyv_load_tillz_ulong(data_out, count);
        npyv_store_till_ulong(data_out, count, npyv_muladd_ulong(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ulong b0 = (data[0]);
        const npy_ulong c0 = (data_out[0]);
        
#line 340
        const npy_ulong b1 = (data[1]);
        const npy_ulong c1 = (data_out[1]);
        
#line 340
        const npy_ulong b2 = (data[2]);
        const npy_ulong c2 = (data_out[2]);
        
#line 340
        const npy_ulong b3 = (data[3]);
        const npy_ulong c3 = (data_out[3]);
        
        #line 346
        const npy_ulong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ulong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ulong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ulong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ulong b = (*data);
        const npy_ulong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ulong
}

static void
ulong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ulong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_ulong;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_ulong a0 = npyv_loada_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_loada_ulong(data1 + vstep * 0);
            npyv_ulong c0 = npyv_loada_ulong(data_out + vstep * 0);
            
#line 390
            npyv_ulong a1 = npyv_loada_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_loada_ulong(data1 + vstep * 1);
            npyv_ulong c1 = npyv_loada_ulong(data_out + vstep * 1);
            
#line 390
            npyv_ulong a2 = npyv_loada_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_loada_ulong(data1 + vstep * 2);
            npyv_ulong c2 = npyv_loada_ulong(data_out + vstep * 2);
            
#line 390
            npyv_ulong a3 = npyv_loada_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_loada_ulong(data1 + vstep * 3);
            npyv_ulong c3 = npyv_loada_ulong(data_out + vstep * 3);
            
            #line 397
            npyv_ulong abc0 = npyv_muladd_ulong(a0, b0, c0);
            
#line 397
            npyv_ulong abc1 = npyv_muladd_ulong(a1, b1, c1);
            
#line 397
            npyv_ulong abc2 = npyv_muladd_ulong(a2, b2, c2);
            
#line 397
            npyv_ulong abc3 = npyv_muladd_ulong(a3, b3, c3);
            
            #line 402
            npyv_storea_ulong(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_ulong a0 = npyv_load_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_load_ulong(data1 + vstep * 0);
            npyv_ulong c0 = npyv_load_ulong(data_out + vstep * 0);
            
#line 390
            npyv_ulong a1 = npyv_load_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_load_ulong(data1 + vstep * 1);
            npyv_ulong c1 = npyv_load_ulong(data_out + vstep * 1);
            
#line 390
            npyv_ulong a2 = npyv_load_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_load_ulong(data1 + vstep * 2);
            npyv_ulong c2 = npyv_load_ulong(data_out + vstep * 2);
            
#line 390
            npyv_ulong a3 = npyv_load_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_load_ulong(data1 + vstep * 3);
            npyv_ulong c3 = npyv_load_ulong(data_out + vstep * 3);
            
            #line 397
            npyv_ulong abc0 = npyv_muladd_ulong(a0, b0, c0);
            
#line 397
            npyv_ulong abc1 = npyv_muladd_ulong(a1, b1, c1);
            
#line 397
            npyv_ulong abc2 = npyv_muladd_ulong(a2, b2, c2);
            
#line 397
            npyv_ulong abc3 = npyv_muladd_ulong(a3, b3, c3);
            
            #line 402
            npyv_store_ulong(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_ulong(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_ulong(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data0, count);
        npyv_ulong b = npyv_load_tillz_ulong(data1, count);
        npyv_ulong c = npyv_load_tillz_ulong(data_out, count);
        npyv_store_till_ulong(data_out, count, npyv_muladd_ulong(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ulong a0 = (data0[0]);
        const npy_ulong b0 = (data1[0]);
        const npy_ulong c0 = (data_out[0]);
        
#line 420
        const npy_ulong a1 = (data0[1]);
        const npy_ulong b1 = (data1[1]);
        const npy_ulong c1 = (data_out[1]);
        
#line 420
        const npy_ulong a2 = (data0[2]);
        const npy_ulong b2 = (data1[2]);
        const npy_ulong c2 = (data_out[2]);
        
#line 420
        const npy_ulong a3 = (data0[3]);
        const npy_ulong b3 = (data1[3]);
        const npy_ulong c3 = (data_out[3]);
        
        #line 427
        const npy_ulong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ulong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ulong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ulong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ulong a = (*data0);
        const npy_ulong b = (*data1);
        const npy_ulong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ulong

}

/* Some extra specializations for the two operand case */
static void
ulong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong value0 = (*(npy_ulong *)dataptr[0]);
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ulong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ulong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong value1 = (*(npy_ulong *)dataptr[1]);
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ulong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong accum = 0;

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_ulong;
    npyv_ulong v_accum = npyv_zero_ulong();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_ulong a0 = npyv_loada_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_loada_ulong(data1 + vstep * 0);
            
#line 501
            npyv_ulong a1 = npyv_loada_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_loada_ulong(data1 + vstep * 1);
            
#line 501
            npyv_ulong a2 = npyv_loada_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_loada_ulong(data1 + vstep * 2);
            
#line 501
            npyv_ulong a3 = npyv_loada_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_loada_ulong(data1 + vstep * 3);
            
            npyv_ulong ab3 = npyv_muladd_ulong(a3, b3, v_accum);
            npyv_ulong ab2 = npyv_muladd_ulong(a2, b2, ab3);
            npyv_ulong ab1 = npyv_muladd_ulong(a1, b1, ab2);
                   v_accum = npyv_muladd_ulong(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_ulong a0 = npyv_load_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_load_ulong(data1 + vstep * 0);
            
#line 501
            npyv_ulong a1 = npyv_load_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_load_ulong(data1 + vstep * 1);
            
#line 501
            npyv_ulong a2 = npyv_load_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_load_ulong(data1 + vstep * 2);
            
#line 501
            npyv_ulong a3 = npyv_load_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_load_ulong(data1 + vstep * 3);
            
            npyv_ulong ab3 = npyv_muladd_ulong(a3, b3, v_accum);
            npyv_ulong ab2 = npyv_muladd_ulong(a2, b2, ab3);
            npyv_ulong ab1 = npyv_muladd_ulong(a1, b1, ab2);
                   v_accum = npyv_muladd_ulong(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data0, count);
        npyv_ulong b = npyv_load_tillz_ulong(data1, count);
        v_accum = npyv_muladd_ulong(a, b, v_accum);
    }
    accum = npyv_sum_ulong(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ulong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ulong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ulong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ulong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ulong a = (*data0);
        const npy_ulong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ulong
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong value0 = (*(npy_ulong *)dataptr[0]);
    npy_ulong accum = ulong_sum_of_arr(data1, count);
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong value1 = (*(npy_ulong *)dataptr[1]);
    npy_ulong accum = ulong_sum_of_arr(data0, count);
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
ulong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data2 = (npy_ulong *)dataptr[2];
    npy_ulong *data_out = (npy_ulong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
ulong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        *(npy_ulong *)dataptr[nop] = (temp +
                                           (*(npy_ulong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ulong);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ulong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ulong *data = (npy_ulong *)dataptr[0];
    npy_ulong accum = ulong_sum_of_arr(data, count);
    *((npy_ulong *)dataptr[1]) = (accum + (*((npy_ulong *)dataptr[1])));
#else
    npy_ulong accum_re = 0, accum_im = 0;
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ulong re01 = data0[0] + data0[2];
        const npy_ulong re23 = data0[4] + data0[6];
        const npy_ulong im13 = data0[1] + data0[3];
        const npy_ulong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ulong *)dataptr[1])[0] += accum_re;
    ((npy_ulong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
ulong_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ulong accum_re = 0, accum_im = 0;
#else
    npy_ulong accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_ulong *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_ulong *)data0) *
                 (*(npy_ulong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_ulong *)data0) *
                 (*(npy_ulong *)data1) *
                 (*(npy_ulong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_ulong *)data0)[0];
        accum_im += ((npy_ulong *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_ulong *)dataptr[3])[0] += accum_re;
    ((npy_ulong *)dataptr[3])[1] += accum_im;
#  else
    ((npy_ulong *)dataptr[nop])[0] += accum_re;
    ((npy_ulong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_ulong *)dataptr[3]) = (accum +
                                    (*((npy_ulong *)dataptr[3])));
#  else
    *((npy_ulong *)dataptr[nop]) = (accum +
                                    (*((npy_ulong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ulong_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) *
                                         (*(npy_ulong *)data1) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_ulong *)data_out = ((*(npy_ulong *)data0) *
                                         (*(npy_ulong *)data1) *
                                         (*(npy_ulong *)data2) +
                                         (*(npy_ulong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        *(npy_ulong *)dataptr[nop] = (temp +
                                           (*(npy_ulong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_ulong *)data_out)[0] = ((npy_ulong *)data0)[0] +
                                         ((npy_ulong *)data_out)[0];
        ((npy_ulong *)data_out)[1] = ((npy_ulong *)data0)[1] +
                                         ((npy_ulong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
ulong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data_out = (npy_ulong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ulong *)data_out + 2*6)[0] =
                                    ((npy_ulong *)data0 + 2*6)[0] +
                                    ((npy_ulong *)data_out + 2*6)[0];
            ((npy_ulong *)data_out + 2*6)[1] =
                                    ((npy_ulong *)data0 + 2*6)[1] +
                                    ((npy_ulong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ulong *)data_out + 2*5)[0] =
                                    ((npy_ulong *)data0 + 2*5)[0] +
                                    ((npy_ulong *)data_out + 2*5)[0];
            ((npy_ulong *)data_out + 2*5)[1] =
                                    ((npy_ulong *)data0 + 2*5)[1] +
                                    ((npy_ulong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ulong *)data_out + 2*4)[0] =
                                    ((npy_ulong *)data0 + 2*4)[0] +
                                    ((npy_ulong *)data_out + 2*4)[0];
            ((npy_ulong *)data_out + 2*4)[1] =
                                    ((npy_ulong *)data0 + 2*4)[1] +
                                    ((npy_ulong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ulong *)data_out + 2*3)[0] =
                                    ((npy_ulong *)data0 + 2*3)[0] +
                                    ((npy_ulong *)data_out + 2*3)[0];
            ((npy_ulong *)data_out + 2*3)[1] =
                                    ((npy_ulong *)data0 + 2*3)[1] +
                                    ((npy_ulong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ulong *)data_out + 2*2)[0] =
                                    ((npy_ulong *)data0 + 2*2)[0] +
                                    ((npy_ulong *)data_out + 2*2)[0];
            ((npy_ulong *)data_out + 2*2)[1] =
                                    ((npy_ulong *)data0 + 2*2)[1] +
                                    ((npy_ulong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ulong *)data_out + 2*1)[0] =
                                    ((npy_ulong *)data0 + 2*1)[0] +
                                    ((npy_ulong *)data_out + 2*1)[0];
            ((npy_ulong *)data_out + 2*1)[1] =
                                    ((npy_ulong *)data0 + 2*1)[1] +
                                    ((npy_ulong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ulong *)data_out + 2*0)[0] =
                                    ((npy_ulong *)data0 + 2*0)[0] +
                                    ((npy_ulong *)data_out + 2*0)[0];
            ((npy_ulong *)data_out + 2*0)[1] =
                                    ((npy_ulong *)data0 + 2*0)[1] +
                                    ((npy_ulong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ulong *)data_out + 2*0)[0] =
                                ((npy_ulong *)data0 + 2*0)[0] +
                                ((npy_ulong *)data_out + 2*0)[0];
        ((npy_ulong *)data_out + 2*0)[1] =
                                ((npy_ulong *)data0 + 2*0)[1] +
                                ((npy_ulong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ulong *)data_out + 2*1)[0] =
                                ((npy_ulong *)data0 + 2*1)[0] +
                                ((npy_ulong *)data_out + 2*1)[0];
        ((npy_ulong *)data_out + 2*1)[1] =
                                ((npy_ulong *)data0 + 2*1)[1] +
                                ((npy_ulong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ulong *)data_out + 2*2)[0] =
                                ((npy_ulong *)data0 + 2*2)[0] +
                                ((npy_ulong *)data_out + 2*2)[0];
        ((npy_ulong *)data_out + 2*2)[1] =
                                ((npy_ulong *)data0 + 2*2)[1] +
                                ((npy_ulong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ulong *)data_out + 2*3)[0] =
                                ((npy_ulong *)data0 + 2*3)[0] +
                                ((npy_ulong *)data_out + 2*3)[0];
        ((npy_ulong *)data_out + 2*3)[1] =
                                ((npy_ulong *)data0 + 2*3)[1] +
                                ((npy_ulong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ulong *)data_out + 2*4)[0] =
                                ((npy_ulong *)data0 + 2*4)[0] +
                                ((npy_ulong *)data_out + 2*4)[0];
        ((npy_ulong *)data_out + 2*4)[1] =
                                ((npy_ulong *)data0 + 2*4)[1] +
                                ((npy_ulong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ulong *)data_out + 2*5)[0] =
                                ((npy_ulong *)data0 + 2*5)[0] +
                                ((npy_ulong *)data_out + 2*5)[0];
        ((npy_ulong *)data_out + 2*5)[1] =
                                ((npy_ulong *)data0 + 2*5)[1] +
                                ((npy_ulong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ulong *)data_out + 2*6)[0] =
                                ((npy_ulong *)data0 + 2*6)[0] +
                                ((npy_ulong *)data_out + 2*6)[0];
        ((npy_ulong *)data_out + 2*6)[1] =
                                ((npy_ulong *)data0 + 2*6)[1] +
                                ((npy_ulong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ulong *)data_out + 2*7)[0] =
                                ((npy_ulong *)data0 + 2*7)[0] +
                                ((npy_ulong *)data_out + 2*7)[0];
        ((npy_ulong *)data_out + 2*7)[1] =
                                ((npy_ulong *)data0 + 2*7)[1] +
                                ((npy_ulong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ulong_sum_of_products_muladd(npy_ulong *data, npy_ulong *data_out, npy_ulong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_ulong;
    const npyv_ulong v_scalar = npyv_setall_ulong(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_ulong b0 = npyv_loada_ulong(data + vstep * 0);
            npyv_ulong c0 = npyv_loada_ulong(data_out + vstep * 0);
            
#line 312
            npyv_ulong b1 = npyv_loada_ulong(data + vstep * 1);
            npyv_ulong c1 = npyv_loada_ulong(data_out + vstep * 1);
            
#line 312
            npyv_ulong b2 = npyv_loada_ulong(data + vstep * 2);
            npyv_ulong c2 = npyv_loada_ulong(data_out + vstep * 2);
            
#line 312
            npyv_ulong b3 = npyv_loada_ulong(data + vstep * 3);
            npyv_ulong c3 = npyv_loada_ulong(data_out + vstep * 3);
            
            #line 318
            npyv_ulong abc0 = npyv_muladd_ulong(v_scalar, b0, c0);
            
#line 318
            npyv_ulong abc1 = npyv_muladd_ulong(v_scalar, b1, c1);
            
#line 318
            npyv_ulong abc2 = npyv_muladd_ulong(v_scalar, b2, c2);
            
#line 318
            npyv_ulong abc3 = npyv_muladd_ulong(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_ulong(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_ulong b0 = npyv_load_ulong(data + vstep * 0);
            npyv_ulong c0 = npyv_load_ulong(data_out + vstep * 0);
            
#line 312
            npyv_ulong b1 = npyv_load_ulong(data + vstep * 1);
            npyv_ulong c1 = npyv_load_ulong(data_out + vstep * 1);
            
#line 312
            npyv_ulong b2 = npyv_load_ulong(data + vstep * 2);
            npyv_ulong c2 = npyv_load_ulong(data_out + vstep * 2);
            
#line 312
            npyv_ulong b3 = npyv_load_ulong(data + vstep * 3);
            npyv_ulong c3 = npyv_load_ulong(data_out + vstep * 3);
            
            #line 318
            npyv_ulong abc0 = npyv_muladd_ulong(v_scalar, b0, c0);
            
#line 318
            npyv_ulong abc1 = npyv_muladd_ulong(v_scalar, b1, c1);
            
#line 318
            npyv_ulong abc2 = npyv_muladd_ulong(v_scalar, b2, c2);
            
#line 318
            npyv_ulong abc3 = npyv_muladd_ulong(v_scalar, b3, c3);
            
            #line 323
            npyv_store_ulong(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_ulong(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_ulong(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data, count);
        npyv_ulong b = npyv_load_tillz_ulong(data_out, count);
        npyv_store_till_ulong(data_out, count, npyv_muladd_ulong(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ulong b0 = (data[0]);
        const npy_ulong c0 = (data_out[0]);
        
#line 340
        const npy_ulong b1 = (data[1]);
        const npy_ulong c1 = (data_out[1]);
        
#line 340
        const npy_ulong b2 = (data[2]);
        const npy_ulong c2 = (data_out[2]);
        
#line 340
        const npy_ulong b3 = (data[3]);
        const npy_ulong c3 = (data_out[3]);
        
        #line 346
        const npy_ulong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ulong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ulong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ulong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ulong b = (*data);
        const npy_ulong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ulong
}

static void
ulong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ulong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_ulong;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_ulong a0 = npyv_loada_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_loada_ulong(data1 + vstep * 0);
            npyv_ulong c0 = npyv_loada_ulong(data_out + vstep * 0);
            
#line 390
            npyv_ulong a1 = npyv_loada_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_loada_ulong(data1 + vstep * 1);
            npyv_ulong c1 = npyv_loada_ulong(data_out + vstep * 1);
            
#line 390
            npyv_ulong a2 = npyv_loada_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_loada_ulong(data1 + vstep * 2);
            npyv_ulong c2 = npyv_loada_ulong(data_out + vstep * 2);
            
#line 390
            npyv_ulong a3 = npyv_loada_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_loada_ulong(data1 + vstep * 3);
            npyv_ulong c3 = npyv_loada_ulong(data_out + vstep * 3);
            
            #line 397
            npyv_ulong abc0 = npyv_muladd_ulong(a0, b0, c0);
            
#line 397
            npyv_ulong abc1 = npyv_muladd_ulong(a1, b1, c1);
            
#line 397
            npyv_ulong abc2 = npyv_muladd_ulong(a2, b2, c2);
            
#line 397
            npyv_ulong abc3 = npyv_muladd_ulong(a3, b3, c3);
            
            #line 402
            npyv_storea_ulong(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_ulong a0 = npyv_load_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_load_ulong(data1 + vstep * 0);
            npyv_ulong c0 = npyv_load_ulong(data_out + vstep * 0);
            
#line 390
            npyv_ulong a1 = npyv_load_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_load_ulong(data1 + vstep * 1);
            npyv_ulong c1 = npyv_load_ulong(data_out + vstep * 1);
            
#line 390
            npyv_ulong a2 = npyv_load_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_load_ulong(data1 + vstep * 2);
            npyv_ulong c2 = npyv_load_ulong(data_out + vstep * 2);
            
#line 390
            npyv_ulong a3 = npyv_load_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_load_ulong(data1 + vstep * 3);
            npyv_ulong c3 = npyv_load_ulong(data_out + vstep * 3);
            
            #line 397
            npyv_ulong abc0 = npyv_muladd_ulong(a0, b0, c0);
            
#line 397
            npyv_ulong abc1 = npyv_muladd_ulong(a1, b1, c1);
            
#line 397
            npyv_ulong abc2 = npyv_muladd_ulong(a2, b2, c2);
            
#line 397
            npyv_ulong abc3 = npyv_muladd_ulong(a3, b3, c3);
            
            #line 402
            npyv_store_ulong(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_ulong(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_ulong(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_ulong(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data0, count);
        npyv_ulong b = npyv_load_tillz_ulong(data1, count);
        npyv_ulong c = npyv_load_tillz_ulong(data_out, count);
        npyv_store_till_ulong(data_out, count, npyv_muladd_ulong(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ulong a0 = (data0[0]);
        const npy_ulong b0 = (data1[0]);
        const npy_ulong c0 = (data_out[0]);
        
#line 420
        const npy_ulong a1 = (data0[1]);
        const npy_ulong b1 = (data1[1]);
        const npy_ulong c1 = (data_out[1]);
        
#line 420
        const npy_ulong a2 = (data0[2]);
        const npy_ulong b2 = (data1[2]);
        const npy_ulong c2 = (data_out[2]);
        
#line 420
        const npy_ulong a3 = (data0[3]);
        const npy_ulong b3 = (data1[3]);
        const npy_ulong c3 = (data_out[3]);
        
        #line 427
        const npy_ulong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ulong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ulong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ulong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ulong a = (*data0);
        const npy_ulong b = (*data1);
        const npy_ulong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ulong

}

/* Some extra specializations for the two operand case */
static void
ulong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong value0 = (*(npy_ulong *)dataptr[0]);
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ulong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ulong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong value1 = (*(npy_ulong *)dataptr[1]);
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data_out = (npy_ulong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ulong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong accum = 0;

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ulong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_ulong;
    npyv_ulong v_accum = npyv_zero_ulong();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_ulong a0 = npyv_loada_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_loada_ulong(data1 + vstep * 0);
            
#line 501
            npyv_ulong a1 = npyv_loada_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_loada_ulong(data1 + vstep * 1);
            
#line 501
            npyv_ulong a2 = npyv_loada_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_loada_ulong(data1 + vstep * 2);
            
#line 501
            npyv_ulong a3 = npyv_loada_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_loada_ulong(data1 + vstep * 3);
            
            npyv_ulong ab3 = npyv_muladd_ulong(a3, b3, v_accum);
            npyv_ulong ab2 = npyv_muladd_ulong(a2, b2, ab3);
            npyv_ulong ab1 = npyv_muladd_ulong(a1, b1, ab2);
                   v_accum = npyv_muladd_ulong(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_ulong a0 = npyv_load_ulong(data0 + vstep * 0);
            npyv_ulong b0 = npyv_load_ulong(data1 + vstep * 0);
            
#line 501
            npyv_ulong a1 = npyv_load_ulong(data0 + vstep * 1);
            npyv_ulong b1 = npyv_load_ulong(data1 + vstep * 1);
            
#line 501
            npyv_ulong a2 = npyv_load_ulong(data0 + vstep * 2);
            npyv_ulong b2 = npyv_load_ulong(data1 + vstep * 2);
            
#line 501
            npyv_ulong a3 = npyv_load_ulong(data0 + vstep * 3);
            npyv_ulong b3 = npyv_load_ulong(data1 + vstep * 3);
            
            npyv_ulong ab3 = npyv_muladd_ulong(a3, b3, v_accum);
            npyv_ulong ab2 = npyv_muladd_ulong(a2, b2, ab3);
            npyv_ulong ab1 = npyv_muladd_ulong(a1, b1, ab2);
                   v_accum = npyv_muladd_ulong(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_ulong a = npyv_load_tillz_ulong(data0, count);
        npyv_ulong b = npyv_load_tillz_ulong(data1, count);
        v_accum = npyv_muladd_ulong(a, b, v_accum);
    }
    accum = npyv_sum_ulong(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ulong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ulong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ulong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ulong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ulong a = (*data0);
        const npy_ulong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ulong
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong value0 = (*(npy_ulong *)dataptr[0]);
    npy_ulong accum = ulong_sum_of_arr(data1, count);
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong value1 = (*(npy_ulong *)dataptr[1]);
    npy_ulong accum = ulong_sum_of_arr(data0, count);
    *(npy_ulong *)dataptr[2] = ((*(npy_ulong *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
ulong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
    npy_ulong *data1 = (npy_ulong *)dataptr[1];
    npy_ulong *data2 = (npy_ulong *)dataptr[2];
    npy_ulong *data_out = (npy_ulong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
ulong_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        *(npy_ulong *)dataptr[nop] = (temp +
                                           (*(npy_ulong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ulong);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ulong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
ulong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ulong *data = (npy_ulong *)dataptr[0];
    npy_ulong accum = ulong_sum_of_arr(data, count);
    *((npy_ulong *)dataptr[1]) = (accum + (*((npy_ulong *)dataptr[1])));
#else
    npy_ulong accum_re = 0, accum_im = 0;
    npy_ulong *data0 = (npy_ulong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ulong re01 = data0[0] + data0[2];
        const npy_ulong re23 = data0[4] + data0[6];
        const npy_ulong im13 = data0[1] + data0[3];
        const npy_ulong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ulong *)dataptr[1])[0] += accum_re;
    ((npy_ulong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
ulong_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ulong accum_re = 0, accum_im = 0;
#else
    npy_ulong accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulong_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_ulong *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_ulong *)data0) *
                 (*(npy_ulong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_ulong *)data0) *
                 (*(npy_ulong *)data1) *
                 (*(npy_ulong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ulong temp = (*(npy_ulong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_ulong *)data0)[0];
        accum_im += ((npy_ulong *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulong re, im, tmp;
        int i;
        re = ((npy_ulong *)dataptr[0])[0];
        im = ((npy_ulong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulong *)dataptr[i])[0] -
                  im * ((npy_ulong *)dataptr[i])[1];
            im = re * ((npy_ulong *)dataptr[i])[1] +
                 im * ((npy_ulong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_ulong *)dataptr[1000])[0] += accum_re;
    ((npy_ulong *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_ulong *)dataptr[nop])[0] += accum_re;
    ((npy_ulong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_ulong *)dataptr[1000]) = (accum +
                                    (*((npy_ulong *)dataptr[1000])));
#  else
    *((npy_ulong *)dataptr[nop]) = (accum +
                                    (*((npy_ulong *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_ulonglong ulonglong_sum_of_arr(npy_ulonglong *data, npy_intp count)
{
    npy_ulonglong accum = 0;
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_u64;
    npyv_u64 v_accum = npyv_zero_u64();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_u64 a0 = npyv_loada_u64(data + vstep * 0);
            
#line 96
            npyv_u64 a1 = npyv_loada_u64(data + vstep * 1);
            
#line 96
            npyv_u64 a2 = npyv_loada_u64(data + vstep * 2);
            
#line 96
            npyv_u64 a3 = npyv_loada_u64(data + vstep * 3);
            
            npyv_u64 a01   = npyv_add_u64(a0, a1);
            npyv_u64 a23   = npyv_add_u64(a2, a3);
            npyv_u64 a0123 = npyv_add_u64(a01, a23);
                     v_accum = npyv_add_u64(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_u64 a0 = npyv_load_u64(data + vstep * 0);
            
#line 96
            npyv_u64 a1 = npyv_load_u64(data + vstep * 1);
            
#line 96
            npyv_u64 a2 = npyv_load_u64(data + vstep * 2);
            
#line 96
            npyv_u64 a3 = npyv_load_u64(data + vstep * 3);
            
            npyv_u64 a01   = npyv_add_u64(a0, a1);
            npyv_u64 a23   = npyv_add_u64(a2, a3);
            npyv_u64 a0123 = npyv_add_u64(a01, a23);
                     v_accum = npyv_add_u64(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data, count);
        v_accum = npyv_add_u64(a, v_accum);
    }
    accum = npyv_sum_u64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_ulonglong a01 = (*data) + (data[1]);
        const npy_ulonglong a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_ulonglong
    return accum;
}
#endif

#line 131
static void
ulonglong_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) *
                                         (*(npy_ulonglong *)data1) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) *
                                         (*(npy_ulonglong *)data1) *
                                         (*(npy_ulonglong *)data2) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        *(npy_ulonglong *)dataptr[nop] = (temp +
                                           (*(npy_ulonglong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_ulonglong *)data_out)[0] = ((npy_ulonglong *)data0)[0] +
                                         ((npy_ulonglong *)data_out)[0];
        ((npy_ulonglong *)data_out)[1] = ((npy_ulonglong *)data0)[1] +
                                         ((npy_ulonglong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
ulonglong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ulonglong *)data_out + 2*6)[0] =
                                    ((npy_ulonglong *)data0 + 2*6)[0] +
                                    ((npy_ulonglong *)data_out + 2*6)[0];
            ((npy_ulonglong *)data_out + 2*6)[1] =
                                    ((npy_ulonglong *)data0 + 2*6)[1] +
                                    ((npy_ulonglong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ulonglong *)data_out + 2*5)[0] =
                                    ((npy_ulonglong *)data0 + 2*5)[0] +
                                    ((npy_ulonglong *)data_out + 2*5)[0];
            ((npy_ulonglong *)data_out + 2*5)[1] =
                                    ((npy_ulonglong *)data0 + 2*5)[1] +
                                    ((npy_ulonglong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ulonglong *)data_out + 2*4)[0] =
                                    ((npy_ulonglong *)data0 + 2*4)[0] +
                                    ((npy_ulonglong *)data_out + 2*4)[0];
            ((npy_ulonglong *)data_out + 2*4)[1] =
                                    ((npy_ulonglong *)data0 + 2*4)[1] +
                                    ((npy_ulonglong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ulonglong *)data_out + 2*3)[0] =
                                    ((npy_ulonglong *)data0 + 2*3)[0] +
                                    ((npy_ulonglong *)data_out + 2*3)[0];
            ((npy_ulonglong *)data_out + 2*3)[1] =
                                    ((npy_ulonglong *)data0 + 2*3)[1] +
                                    ((npy_ulonglong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ulonglong *)data_out + 2*2)[0] =
                                    ((npy_ulonglong *)data0 + 2*2)[0] +
                                    ((npy_ulonglong *)data_out + 2*2)[0];
            ((npy_ulonglong *)data_out + 2*2)[1] =
                                    ((npy_ulonglong *)data0 + 2*2)[1] +
                                    ((npy_ulonglong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ulonglong *)data_out + 2*1)[0] =
                                    ((npy_ulonglong *)data0 + 2*1)[0] +
                                    ((npy_ulonglong *)data_out + 2*1)[0];
            ((npy_ulonglong *)data_out + 2*1)[1] =
                                    ((npy_ulonglong *)data0 + 2*1)[1] +
                                    ((npy_ulonglong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ulonglong *)data_out + 2*0)[0] =
                                    ((npy_ulonglong *)data0 + 2*0)[0] +
                                    ((npy_ulonglong *)data_out + 2*0)[0];
            ((npy_ulonglong *)data_out + 2*0)[1] =
                                    ((npy_ulonglong *)data0 + 2*0)[1] +
                                    ((npy_ulonglong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*0)[0] =
                                ((npy_ulonglong *)data0 + 2*0)[0] +
                                ((npy_ulonglong *)data_out + 2*0)[0];
        ((npy_ulonglong *)data_out + 2*0)[1] =
                                ((npy_ulonglong *)data0 + 2*0)[1] +
                                ((npy_ulonglong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*1)[0] =
                                ((npy_ulonglong *)data0 + 2*1)[0] +
                                ((npy_ulonglong *)data_out + 2*1)[0];
        ((npy_ulonglong *)data_out + 2*1)[1] =
                                ((npy_ulonglong *)data0 + 2*1)[1] +
                                ((npy_ulonglong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*2)[0] =
                                ((npy_ulonglong *)data0 + 2*2)[0] +
                                ((npy_ulonglong *)data_out + 2*2)[0];
        ((npy_ulonglong *)data_out + 2*2)[1] =
                                ((npy_ulonglong *)data0 + 2*2)[1] +
                                ((npy_ulonglong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*3)[0] =
                                ((npy_ulonglong *)data0 + 2*3)[0] +
                                ((npy_ulonglong *)data_out + 2*3)[0];
        ((npy_ulonglong *)data_out + 2*3)[1] =
                                ((npy_ulonglong *)data0 + 2*3)[1] +
                                ((npy_ulonglong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*4)[0] =
                                ((npy_ulonglong *)data0 + 2*4)[0] +
                                ((npy_ulonglong *)data_out + 2*4)[0];
        ((npy_ulonglong *)data_out + 2*4)[1] =
                                ((npy_ulonglong *)data0 + 2*4)[1] +
                                ((npy_ulonglong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*5)[0] =
                                ((npy_ulonglong *)data0 + 2*5)[0] +
                                ((npy_ulonglong *)data_out + 2*5)[0];
        ((npy_ulonglong *)data_out + 2*5)[1] =
                                ((npy_ulonglong *)data0 + 2*5)[1] +
                                ((npy_ulonglong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*6)[0] =
                                ((npy_ulonglong *)data0 + 2*6)[0] +
                                ((npy_ulonglong *)data_out + 2*6)[0];
        ((npy_ulonglong *)data_out + 2*6)[1] =
                                ((npy_ulonglong *)data0 + 2*6)[1] +
                                ((npy_ulonglong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*7)[0] =
                                ((npy_ulonglong *)data0 + 2*7)[0] +
                                ((npy_ulonglong *)data_out + 2*7)[0];
        ((npy_ulonglong *)data_out + 2*7)[1] =
                                ((npy_ulonglong *)data0 + 2*7)[1] +
                                ((npy_ulonglong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_muladd(npy_ulonglong *data, npy_ulonglong *data_out, npy_ulonglong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u64;
    const npyv_u64 v_scalar = npyv_setall_u64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u64 b0 = npyv_loada_u64(data + vstep * 0);
            npyv_u64 c0 = npyv_loada_u64(data_out + vstep * 0);
            
#line 312
            npyv_u64 b1 = npyv_loada_u64(data + vstep * 1);
            npyv_u64 c1 = npyv_loada_u64(data_out + vstep * 1);
            
#line 312
            npyv_u64 b2 = npyv_loada_u64(data + vstep * 2);
            npyv_u64 c2 = npyv_loada_u64(data_out + vstep * 2);
            
#line 312
            npyv_u64 b3 = npyv_loada_u64(data + vstep * 3);
            npyv_u64 c3 = npyv_loada_u64(data_out + vstep * 3);
            
            #line 318
            npyv_u64 abc0 = npyv_muladd_u64(v_scalar, b0, c0);
            
#line 318
            npyv_u64 abc1 = npyv_muladd_u64(v_scalar, b1, c1);
            
#line 318
            npyv_u64 abc2 = npyv_muladd_u64(v_scalar, b2, c2);
            
#line 318
            npyv_u64 abc3 = npyv_muladd_u64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u64 b0 = npyv_load_u64(data + vstep * 0);
            npyv_u64 c0 = npyv_load_u64(data_out + vstep * 0);
            
#line 312
            npyv_u64 b1 = npyv_load_u64(data + vstep * 1);
            npyv_u64 c1 = npyv_load_u64(data_out + vstep * 1);
            
#line 312
            npyv_u64 b2 = npyv_load_u64(data + vstep * 2);
            npyv_u64 c2 = npyv_load_u64(data_out + vstep * 2);
            
#line 312
            npyv_u64 b3 = npyv_load_u64(data + vstep * 3);
            npyv_u64 c3 = npyv_load_u64(data_out + vstep * 3);
            
            #line 318
            npyv_u64 abc0 = npyv_muladd_u64(v_scalar, b0, c0);
            
#line 318
            npyv_u64 abc1 = npyv_muladd_u64(v_scalar, b1, c1);
            
#line 318
            npyv_u64 abc2 = npyv_muladd_u64(v_scalar, b2, c2);
            
#line 318
            npyv_u64 abc3 = npyv_muladd_u64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data, count);
        npyv_u64 b = npyv_load_tillz_u64(data_out, count);
        npyv_store_till_u64(data_out, count, npyv_muladd_u64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ulonglong b0 = (data[0]);
        const npy_ulonglong c0 = (data_out[0]);
        
#line 340
        const npy_ulonglong b1 = (data[1]);
        const npy_ulonglong c1 = (data_out[1]);
        
#line 340
        const npy_ulonglong b2 = (data[2]);
        const npy_ulonglong c2 = (data_out[2]);
        
#line 340
        const npy_ulonglong b3 = (data[3]);
        const npy_ulonglong c3 = (data_out[3]);
        
        #line 346
        const npy_ulonglong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ulonglong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ulonglong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ulonglong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ulonglong b = (*data);
        const npy_ulonglong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ulonglong
}

static void
ulonglong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ulonglong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u64 a0 = npyv_loada_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_loada_u64(data1 + vstep * 0);
            npyv_u64 c0 = npyv_loada_u64(data_out + vstep * 0);
            
#line 390
            npyv_u64 a1 = npyv_loada_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_loada_u64(data1 + vstep * 1);
            npyv_u64 c1 = npyv_loada_u64(data_out + vstep * 1);
            
#line 390
            npyv_u64 a2 = npyv_loada_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_loada_u64(data1 + vstep * 2);
            npyv_u64 c2 = npyv_loada_u64(data_out + vstep * 2);
            
#line 390
            npyv_u64 a3 = npyv_loada_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_loada_u64(data1 + vstep * 3);
            npyv_u64 c3 = npyv_loada_u64(data_out + vstep * 3);
            
            #line 397
            npyv_u64 abc0 = npyv_muladd_u64(a0, b0, c0);
            
#line 397
            npyv_u64 abc1 = npyv_muladd_u64(a1, b1, c1);
            
#line 397
            npyv_u64 abc2 = npyv_muladd_u64(a2, b2, c2);
            
#line 397
            npyv_u64 abc3 = npyv_muladd_u64(a3, b3, c3);
            
            #line 402
            npyv_storea_u64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u64 a0 = npyv_load_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_load_u64(data1 + vstep * 0);
            npyv_u64 c0 = npyv_load_u64(data_out + vstep * 0);
            
#line 390
            npyv_u64 a1 = npyv_load_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_load_u64(data1 + vstep * 1);
            npyv_u64 c1 = npyv_load_u64(data_out + vstep * 1);
            
#line 390
            npyv_u64 a2 = npyv_load_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_load_u64(data1 + vstep * 2);
            npyv_u64 c2 = npyv_load_u64(data_out + vstep * 2);
            
#line 390
            npyv_u64 a3 = npyv_load_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_load_u64(data1 + vstep * 3);
            npyv_u64 c3 = npyv_load_u64(data_out + vstep * 3);
            
            #line 397
            npyv_u64 abc0 = npyv_muladd_u64(a0, b0, c0);
            
#line 397
            npyv_u64 abc1 = npyv_muladd_u64(a1, b1, c1);
            
#line 397
            npyv_u64 abc2 = npyv_muladd_u64(a2, b2, c2);
            
#line 397
            npyv_u64 abc3 = npyv_muladd_u64(a3, b3, c3);
            
            #line 402
            npyv_store_u64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data0, count);
        npyv_u64 b = npyv_load_tillz_u64(data1, count);
        npyv_u64 c = npyv_load_tillz_u64(data_out, count);
        npyv_store_till_u64(data_out, count, npyv_muladd_u64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ulonglong a0 = (data0[0]);
        const npy_ulonglong b0 = (data1[0]);
        const npy_ulonglong c0 = (data_out[0]);
        
#line 420
        const npy_ulonglong a1 = (data0[1]);
        const npy_ulonglong b1 = (data1[1]);
        const npy_ulonglong c1 = (data_out[1]);
        
#line 420
        const npy_ulonglong a2 = (data0[2]);
        const npy_ulonglong b2 = (data1[2]);
        const npy_ulonglong c2 = (data_out[2]);
        
#line 420
        const npy_ulonglong a3 = (data0[3]);
        const npy_ulonglong b3 = (data1[3]);
        const npy_ulonglong c3 = (data_out[3]);
        
        #line 427
        const npy_ulonglong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ulonglong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ulonglong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ulonglong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ulonglong a = (*data0);
        const npy_ulonglong b = (*data1);
        const npy_ulonglong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ulonglong

}

/* Some extra specializations for the two operand case */
static void
ulonglong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong value0 = (*(npy_ulonglong *)dataptr[0]);
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ulonglong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ulonglong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong value1 = (*(npy_ulonglong *)dataptr[1]);
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ulonglong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong accum = 0;

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u64;
    npyv_u64 v_accum = npyv_zero_u64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u64 a0 = npyv_loada_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_loada_u64(data1 + vstep * 0);
            
#line 501
            npyv_u64 a1 = npyv_loada_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_loada_u64(data1 + vstep * 1);
            
#line 501
            npyv_u64 a2 = npyv_loada_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_loada_u64(data1 + vstep * 2);
            
#line 501
            npyv_u64 a3 = npyv_loada_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_loada_u64(data1 + vstep * 3);
            
            npyv_u64 ab3 = npyv_muladd_u64(a3, b3, v_accum);
            npyv_u64 ab2 = npyv_muladd_u64(a2, b2, ab3);
            npyv_u64 ab1 = npyv_muladd_u64(a1, b1, ab2);
                   v_accum = npyv_muladd_u64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u64 a0 = npyv_load_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_load_u64(data1 + vstep * 0);
            
#line 501
            npyv_u64 a1 = npyv_load_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_load_u64(data1 + vstep * 1);
            
#line 501
            npyv_u64 a2 = npyv_load_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_load_u64(data1 + vstep * 2);
            
#line 501
            npyv_u64 a3 = npyv_load_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_load_u64(data1 + vstep * 3);
            
            npyv_u64 ab3 = npyv_muladd_u64(a3, b3, v_accum);
            npyv_u64 ab2 = npyv_muladd_u64(a2, b2, ab3);
            npyv_u64 ab1 = npyv_muladd_u64(a1, b1, ab2);
                   v_accum = npyv_muladd_u64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data0, count);
        npyv_u64 b = npyv_load_tillz_u64(data1, count);
        v_accum = npyv_muladd_u64(a, b, v_accum);
    }
    accum = npyv_sum_u64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ulonglong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ulonglong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ulonglong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ulonglong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ulonglong a = (*data0);
        const npy_ulonglong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ulonglong
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong value0 = (*(npy_ulonglong *)dataptr[0]);
    npy_ulonglong accum = ulonglong_sum_of_arr(data1, count);
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong value1 = (*(npy_ulonglong *)dataptr[1]);
    npy_ulonglong accum = ulonglong_sum_of_arr(data0, count);
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
ulonglong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data2 = (npy_ulonglong *)dataptr[2];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
ulonglong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        *(npy_ulonglong *)dataptr[nop] = (temp +
                                           (*(npy_ulonglong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ulonglong);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ulonglong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ulonglong *data = (npy_ulonglong *)dataptr[0];
    npy_ulonglong accum = ulonglong_sum_of_arr(data, count);
    *((npy_ulonglong *)dataptr[1]) = (accum + (*((npy_ulonglong *)dataptr[1])));
#else
    npy_ulonglong accum_re = 0, accum_im = 0;
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ulonglong re01 = data0[0] + data0[2];
        const npy_ulonglong re23 = data0[4] + data0[6];
        const npy_ulonglong im13 = data0[1] + data0[3];
        const npy_ulonglong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ulonglong *)dataptr[1])[0] += accum_re;
    ((npy_ulonglong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
ulonglong_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ulonglong accum_re = 0, accum_im = 0;
#else
    npy_ulonglong accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_ulonglong *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_ulonglong *)data0) *
                 (*(npy_ulonglong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_ulonglong *)data0) *
                 (*(npy_ulonglong *)data1) *
                 (*(npy_ulonglong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_ulonglong *)data0)[0];
        accum_im += ((npy_ulonglong *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_ulonglong *)dataptr[1])[0] += accum_re;
    ((npy_ulonglong *)dataptr[1])[1] += accum_im;
#  else
    ((npy_ulonglong *)dataptr[nop])[0] += accum_re;
    ((npy_ulonglong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_ulonglong *)dataptr[1]) = (accum +
                                    (*((npy_ulonglong *)dataptr[1])));
#  else
    *((npy_ulonglong *)dataptr[nop]) = (accum +
                                    (*((npy_ulonglong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ulonglong_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) *
                                         (*(npy_ulonglong *)data1) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) *
                                         (*(npy_ulonglong *)data1) *
                                         (*(npy_ulonglong *)data2) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        *(npy_ulonglong *)dataptr[nop] = (temp +
                                           (*(npy_ulonglong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_ulonglong *)data_out)[0] = ((npy_ulonglong *)data0)[0] +
                                         ((npy_ulonglong *)data_out)[0];
        ((npy_ulonglong *)data_out)[1] = ((npy_ulonglong *)data0)[1] +
                                         ((npy_ulonglong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
ulonglong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ulonglong *)data_out + 2*6)[0] =
                                    ((npy_ulonglong *)data0 + 2*6)[0] +
                                    ((npy_ulonglong *)data_out + 2*6)[0];
            ((npy_ulonglong *)data_out + 2*6)[1] =
                                    ((npy_ulonglong *)data0 + 2*6)[1] +
                                    ((npy_ulonglong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ulonglong *)data_out + 2*5)[0] =
                                    ((npy_ulonglong *)data0 + 2*5)[0] +
                                    ((npy_ulonglong *)data_out + 2*5)[0];
            ((npy_ulonglong *)data_out + 2*5)[1] =
                                    ((npy_ulonglong *)data0 + 2*5)[1] +
                                    ((npy_ulonglong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ulonglong *)data_out + 2*4)[0] =
                                    ((npy_ulonglong *)data0 + 2*4)[0] +
                                    ((npy_ulonglong *)data_out + 2*4)[0];
            ((npy_ulonglong *)data_out + 2*4)[1] =
                                    ((npy_ulonglong *)data0 + 2*4)[1] +
                                    ((npy_ulonglong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ulonglong *)data_out + 2*3)[0] =
                                    ((npy_ulonglong *)data0 + 2*3)[0] +
                                    ((npy_ulonglong *)data_out + 2*3)[0];
            ((npy_ulonglong *)data_out + 2*3)[1] =
                                    ((npy_ulonglong *)data0 + 2*3)[1] +
                                    ((npy_ulonglong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ulonglong *)data_out + 2*2)[0] =
                                    ((npy_ulonglong *)data0 + 2*2)[0] +
                                    ((npy_ulonglong *)data_out + 2*2)[0];
            ((npy_ulonglong *)data_out + 2*2)[1] =
                                    ((npy_ulonglong *)data0 + 2*2)[1] +
                                    ((npy_ulonglong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ulonglong *)data_out + 2*1)[0] =
                                    ((npy_ulonglong *)data0 + 2*1)[0] +
                                    ((npy_ulonglong *)data_out + 2*1)[0];
            ((npy_ulonglong *)data_out + 2*1)[1] =
                                    ((npy_ulonglong *)data0 + 2*1)[1] +
                                    ((npy_ulonglong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ulonglong *)data_out + 2*0)[0] =
                                    ((npy_ulonglong *)data0 + 2*0)[0] +
                                    ((npy_ulonglong *)data_out + 2*0)[0];
            ((npy_ulonglong *)data_out + 2*0)[1] =
                                    ((npy_ulonglong *)data0 + 2*0)[1] +
                                    ((npy_ulonglong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*0)[0] =
                                ((npy_ulonglong *)data0 + 2*0)[0] +
                                ((npy_ulonglong *)data_out + 2*0)[0];
        ((npy_ulonglong *)data_out + 2*0)[1] =
                                ((npy_ulonglong *)data0 + 2*0)[1] +
                                ((npy_ulonglong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*1)[0] =
                                ((npy_ulonglong *)data0 + 2*1)[0] +
                                ((npy_ulonglong *)data_out + 2*1)[0];
        ((npy_ulonglong *)data_out + 2*1)[1] =
                                ((npy_ulonglong *)data0 + 2*1)[1] +
                                ((npy_ulonglong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*2)[0] =
                                ((npy_ulonglong *)data0 + 2*2)[0] +
                                ((npy_ulonglong *)data_out + 2*2)[0];
        ((npy_ulonglong *)data_out + 2*2)[1] =
                                ((npy_ulonglong *)data0 + 2*2)[1] +
                                ((npy_ulonglong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*3)[0] =
                                ((npy_ulonglong *)data0 + 2*3)[0] +
                                ((npy_ulonglong *)data_out + 2*3)[0];
        ((npy_ulonglong *)data_out + 2*3)[1] =
                                ((npy_ulonglong *)data0 + 2*3)[1] +
                                ((npy_ulonglong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*4)[0] =
                                ((npy_ulonglong *)data0 + 2*4)[0] +
                                ((npy_ulonglong *)data_out + 2*4)[0];
        ((npy_ulonglong *)data_out + 2*4)[1] =
                                ((npy_ulonglong *)data0 + 2*4)[1] +
                                ((npy_ulonglong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*5)[0] =
                                ((npy_ulonglong *)data0 + 2*5)[0] +
                                ((npy_ulonglong *)data_out + 2*5)[0];
        ((npy_ulonglong *)data_out + 2*5)[1] =
                                ((npy_ulonglong *)data0 + 2*5)[1] +
                                ((npy_ulonglong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*6)[0] =
                                ((npy_ulonglong *)data0 + 2*6)[0] +
                                ((npy_ulonglong *)data_out + 2*6)[0];
        ((npy_ulonglong *)data_out + 2*6)[1] =
                                ((npy_ulonglong *)data0 + 2*6)[1] +
                                ((npy_ulonglong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*7)[0] =
                                ((npy_ulonglong *)data0 + 2*7)[0] +
                                ((npy_ulonglong *)data_out + 2*7)[0];
        ((npy_ulonglong *)data_out + 2*7)[1] =
                                ((npy_ulonglong *)data0 + 2*7)[1] +
                                ((npy_ulonglong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_muladd(npy_ulonglong *data, npy_ulonglong *data_out, npy_ulonglong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u64;
    const npyv_u64 v_scalar = npyv_setall_u64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u64 b0 = npyv_loada_u64(data + vstep * 0);
            npyv_u64 c0 = npyv_loada_u64(data_out + vstep * 0);
            
#line 312
            npyv_u64 b1 = npyv_loada_u64(data + vstep * 1);
            npyv_u64 c1 = npyv_loada_u64(data_out + vstep * 1);
            
#line 312
            npyv_u64 b2 = npyv_loada_u64(data + vstep * 2);
            npyv_u64 c2 = npyv_loada_u64(data_out + vstep * 2);
            
#line 312
            npyv_u64 b3 = npyv_loada_u64(data + vstep * 3);
            npyv_u64 c3 = npyv_loada_u64(data_out + vstep * 3);
            
            #line 318
            npyv_u64 abc0 = npyv_muladd_u64(v_scalar, b0, c0);
            
#line 318
            npyv_u64 abc1 = npyv_muladd_u64(v_scalar, b1, c1);
            
#line 318
            npyv_u64 abc2 = npyv_muladd_u64(v_scalar, b2, c2);
            
#line 318
            npyv_u64 abc3 = npyv_muladd_u64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u64 b0 = npyv_load_u64(data + vstep * 0);
            npyv_u64 c0 = npyv_load_u64(data_out + vstep * 0);
            
#line 312
            npyv_u64 b1 = npyv_load_u64(data + vstep * 1);
            npyv_u64 c1 = npyv_load_u64(data_out + vstep * 1);
            
#line 312
            npyv_u64 b2 = npyv_load_u64(data + vstep * 2);
            npyv_u64 c2 = npyv_load_u64(data_out + vstep * 2);
            
#line 312
            npyv_u64 b3 = npyv_load_u64(data + vstep * 3);
            npyv_u64 c3 = npyv_load_u64(data_out + vstep * 3);
            
            #line 318
            npyv_u64 abc0 = npyv_muladd_u64(v_scalar, b0, c0);
            
#line 318
            npyv_u64 abc1 = npyv_muladd_u64(v_scalar, b1, c1);
            
#line 318
            npyv_u64 abc2 = npyv_muladd_u64(v_scalar, b2, c2);
            
#line 318
            npyv_u64 abc3 = npyv_muladd_u64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data, count);
        npyv_u64 b = npyv_load_tillz_u64(data_out, count);
        npyv_store_till_u64(data_out, count, npyv_muladd_u64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ulonglong b0 = (data[0]);
        const npy_ulonglong c0 = (data_out[0]);
        
#line 340
        const npy_ulonglong b1 = (data[1]);
        const npy_ulonglong c1 = (data_out[1]);
        
#line 340
        const npy_ulonglong b2 = (data[2]);
        const npy_ulonglong c2 = (data_out[2]);
        
#line 340
        const npy_ulonglong b3 = (data[3]);
        const npy_ulonglong c3 = (data_out[3]);
        
        #line 346
        const npy_ulonglong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ulonglong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ulonglong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ulonglong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ulonglong b = (*data);
        const npy_ulonglong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ulonglong
}

static void
ulonglong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ulonglong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u64 a0 = npyv_loada_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_loada_u64(data1 + vstep * 0);
            npyv_u64 c0 = npyv_loada_u64(data_out + vstep * 0);
            
#line 390
            npyv_u64 a1 = npyv_loada_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_loada_u64(data1 + vstep * 1);
            npyv_u64 c1 = npyv_loada_u64(data_out + vstep * 1);
            
#line 390
            npyv_u64 a2 = npyv_loada_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_loada_u64(data1 + vstep * 2);
            npyv_u64 c2 = npyv_loada_u64(data_out + vstep * 2);
            
#line 390
            npyv_u64 a3 = npyv_loada_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_loada_u64(data1 + vstep * 3);
            npyv_u64 c3 = npyv_loada_u64(data_out + vstep * 3);
            
            #line 397
            npyv_u64 abc0 = npyv_muladd_u64(a0, b0, c0);
            
#line 397
            npyv_u64 abc1 = npyv_muladd_u64(a1, b1, c1);
            
#line 397
            npyv_u64 abc2 = npyv_muladd_u64(a2, b2, c2);
            
#line 397
            npyv_u64 abc3 = npyv_muladd_u64(a3, b3, c3);
            
            #line 402
            npyv_storea_u64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u64 a0 = npyv_load_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_load_u64(data1 + vstep * 0);
            npyv_u64 c0 = npyv_load_u64(data_out + vstep * 0);
            
#line 390
            npyv_u64 a1 = npyv_load_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_load_u64(data1 + vstep * 1);
            npyv_u64 c1 = npyv_load_u64(data_out + vstep * 1);
            
#line 390
            npyv_u64 a2 = npyv_load_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_load_u64(data1 + vstep * 2);
            npyv_u64 c2 = npyv_load_u64(data_out + vstep * 2);
            
#line 390
            npyv_u64 a3 = npyv_load_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_load_u64(data1 + vstep * 3);
            npyv_u64 c3 = npyv_load_u64(data_out + vstep * 3);
            
            #line 397
            npyv_u64 abc0 = npyv_muladd_u64(a0, b0, c0);
            
#line 397
            npyv_u64 abc1 = npyv_muladd_u64(a1, b1, c1);
            
#line 397
            npyv_u64 abc2 = npyv_muladd_u64(a2, b2, c2);
            
#line 397
            npyv_u64 abc3 = npyv_muladd_u64(a3, b3, c3);
            
            #line 402
            npyv_store_u64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data0, count);
        npyv_u64 b = npyv_load_tillz_u64(data1, count);
        npyv_u64 c = npyv_load_tillz_u64(data_out, count);
        npyv_store_till_u64(data_out, count, npyv_muladd_u64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ulonglong a0 = (data0[0]);
        const npy_ulonglong b0 = (data1[0]);
        const npy_ulonglong c0 = (data_out[0]);
        
#line 420
        const npy_ulonglong a1 = (data0[1]);
        const npy_ulonglong b1 = (data1[1]);
        const npy_ulonglong c1 = (data_out[1]);
        
#line 420
        const npy_ulonglong a2 = (data0[2]);
        const npy_ulonglong b2 = (data1[2]);
        const npy_ulonglong c2 = (data_out[2]);
        
#line 420
        const npy_ulonglong a3 = (data0[3]);
        const npy_ulonglong b3 = (data1[3]);
        const npy_ulonglong c3 = (data_out[3]);
        
        #line 427
        const npy_ulonglong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ulonglong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ulonglong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ulonglong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ulonglong a = (*data0);
        const npy_ulonglong b = (*data1);
        const npy_ulonglong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ulonglong

}

/* Some extra specializations for the two operand case */
static void
ulonglong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong value0 = (*(npy_ulonglong *)dataptr[0]);
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ulonglong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ulonglong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong value1 = (*(npy_ulonglong *)dataptr[1]);
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ulonglong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong accum = 0;

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u64;
    npyv_u64 v_accum = npyv_zero_u64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u64 a0 = npyv_loada_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_loada_u64(data1 + vstep * 0);
            
#line 501
            npyv_u64 a1 = npyv_loada_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_loada_u64(data1 + vstep * 1);
            
#line 501
            npyv_u64 a2 = npyv_loada_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_loada_u64(data1 + vstep * 2);
            
#line 501
            npyv_u64 a3 = npyv_loada_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_loada_u64(data1 + vstep * 3);
            
            npyv_u64 ab3 = npyv_muladd_u64(a3, b3, v_accum);
            npyv_u64 ab2 = npyv_muladd_u64(a2, b2, ab3);
            npyv_u64 ab1 = npyv_muladd_u64(a1, b1, ab2);
                   v_accum = npyv_muladd_u64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u64 a0 = npyv_load_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_load_u64(data1 + vstep * 0);
            
#line 501
            npyv_u64 a1 = npyv_load_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_load_u64(data1 + vstep * 1);
            
#line 501
            npyv_u64 a2 = npyv_load_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_load_u64(data1 + vstep * 2);
            
#line 501
            npyv_u64 a3 = npyv_load_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_load_u64(data1 + vstep * 3);
            
            npyv_u64 ab3 = npyv_muladd_u64(a3, b3, v_accum);
            npyv_u64 ab2 = npyv_muladd_u64(a2, b2, ab3);
            npyv_u64 ab1 = npyv_muladd_u64(a1, b1, ab2);
                   v_accum = npyv_muladd_u64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data0, count);
        npyv_u64 b = npyv_load_tillz_u64(data1, count);
        v_accum = npyv_muladd_u64(a, b, v_accum);
    }
    accum = npyv_sum_u64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ulonglong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ulonglong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ulonglong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ulonglong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ulonglong a = (*data0);
        const npy_ulonglong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ulonglong
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong value0 = (*(npy_ulonglong *)dataptr[0]);
    npy_ulonglong accum = ulonglong_sum_of_arr(data1, count);
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong value1 = (*(npy_ulonglong *)dataptr[1]);
    npy_ulonglong accum = ulonglong_sum_of_arr(data0, count);
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
ulonglong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data2 = (npy_ulonglong *)dataptr[2];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
ulonglong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        *(npy_ulonglong *)dataptr[nop] = (temp +
                                           (*(npy_ulonglong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ulonglong);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ulonglong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ulonglong *data = (npy_ulonglong *)dataptr[0];
    npy_ulonglong accum = ulonglong_sum_of_arr(data, count);
    *((npy_ulonglong *)dataptr[1]) = (accum + (*((npy_ulonglong *)dataptr[1])));
#else
    npy_ulonglong accum_re = 0, accum_im = 0;
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ulonglong re01 = data0[0] + data0[2];
        const npy_ulonglong re23 = data0[4] + data0[6];
        const npy_ulonglong im13 = data0[1] + data0[3];
        const npy_ulonglong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ulonglong *)dataptr[1])[0] += accum_re;
    ((npy_ulonglong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
ulonglong_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ulonglong accum_re = 0, accum_im = 0;
#else
    npy_ulonglong accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_ulonglong *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_ulonglong *)data0) *
                 (*(npy_ulonglong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_ulonglong *)data0) *
                 (*(npy_ulonglong *)data1) *
                 (*(npy_ulonglong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_ulonglong *)data0)[0];
        accum_im += ((npy_ulonglong *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_ulonglong *)dataptr[2])[0] += accum_re;
    ((npy_ulonglong *)dataptr[2])[1] += accum_im;
#  else
    ((npy_ulonglong *)dataptr[nop])[0] += accum_re;
    ((npy_ulonglong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_ulonglong *)dataptr[2]) = (accum +
                                    (*((npy_ulonglong *)dataptr[2])));
#  else
    *((npy_ulonglong *)dataptr[nop]) = (accum +
                                    (*((npy_ulonglong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ulonglong_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) *
                                         (*(npy_ulonglong *)data1) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) *
                                         (*(npy_ulonglong *)data1) *
                                         (*(npy_ulonglong *)data2) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        *(npy_ulonglong *)dataptr[nop] = (temp +
                                           (*(npy_ulonglong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_ulonglong *)data_out)[0] = ((npy_ulonglong *)data0)[0] +
                                         ((npy_ulonglong *)data_out)[0];
        ((npy_ulonglong *)data_out)[1] = ((npy_ulonglong *)data0)[1] +
                                         ((npy_ulonglong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
ulonglong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ulonglong *)data_out + 2*6)[0] =
                                    ((npy_ulonglong *)data0 + 2*6)[0] +
                                    ((npy_ulonglong *)data_out + 2*6)[0];
            ((npy_ulonglong *)data_out + 2*6)[1] =
                                    ((npy_ulonglong *)data0 + 2*6)[1] +
                                    ((npy_ulonglong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ulonglong *)data_out + 2*5)[0] =
                                    ((npy_ulonglong *)data0 + 2*5)[0] +
                                    ((npy_ulonglong *)data_out + 2*5)[0];
            ((npy_ulonglong *)data_out + 2*5)[1] =
                                    ((npy_ulonglong *)data0 + 2*5)[1] +
                                    ((npy_ulonglong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ulonglong *)data_out + 2*4)[0] =
                                    ((npy_ulonglong *)data0 + 2*4)[0] +
                                    ((npy_ulonglong *)data_out + 2*4)[0];
            ((npy_ulonglong *)data_out + 2*4)[1] =
                                    ((npy_ulonglong *)data0 + 2*4)[1] +
                                    ((npy_ulonglong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ulonglong *)data_out + 2*3)[0] =
                                    ((npy_ulonglong *)data0 + 2*3)[0] +
                                    ((npy_ulonglong *)data_out + 2*3)[0];
            ((npy_ulonglong *)data_out + 2*3)[1] =
                                    ((npy_ulonglong *)data0 + 2*3)[1] +
                                    ((npy_ulonglong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ulonglong *)data_out + 2*2)[0] =
                                    ((npy_ulonglong *)data0 + 2*2)[0] +
                                    ((npy_ulonglong *)data_out + 2*2)[0];
            ((npy_ulonglong *)data_out + 2*2)[1] =
                                    ((npy_ulonglong *)data0 + 2*2)[1] +
                                    ((npy_ulonglong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ulonglong *)data_out + 2*1)[0] =
                                    ((npy_ulonglong *)data0 + 2*1)[0] +
                                    ((npy_ulonglong *)data_out + 2*1)[0];
            ((npy_ulonglong *)data_out + 2*1)[1] =
                                    ((npy_ulonglong *)data0 + 2*1)[1] +
                                    ((npy_ulonglong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ulonglong *)data_out + 2*0)[0] =
                                    ((npy_ulonglong *)data0 + 2*0)[0] +
                                    ((npy_ulonglong *)data_out + 2*0)[0];
            ((npy_ulonglong *)data_out + 2*0)[1] =
                                    ((npy_ulonglong *)data0 + 2*0)[1] +
                                    ((npy_ulonglong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*0)[0] =
                                ((npy_ulonglong *)data0 + 2*0)[0] +
                                ((npy_ulonglong *)data_out + 2*0)[0];
        ((npy_ulonglong *)data_out + 2*0)[1] =
                                ((npy_ulonglong *)data0 + 2*0)[1] +
                                ((npy_ulonglong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*1)[0] =
                                ((npy_ulonglong *)data0 + 2*1)[0] +
                                ((npy_ulonglong *)data_out + 2*1)[0];
        ((npy_ulonglong *)data_out + 2*1)[1] =
                                ((npy_ulonglong *)data0 + 2*1)[1] +
                                ((npy_ulonglong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*2)[0] =
                                ((npy_ulonglong *)data0 + 2*2)[0] +
                                ((npy_ulonglong *)data_out + 2*2)[0];
        ((npy_ulonglong *)data_out + 2*2)[1] =
                                ((npy_ulonglong *)data0 + 2*2)[1] +
                                ((npy_ulonglong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*3)[0] =
                                ((npy_ulonglong *)data0 + 2*3)[0] +
                                ((npy_ulonglong *)data_out + 2*3)[0];
        ((npy_ulonglong *)data_out + 2*3)[1] =
                                ((npy_ulonglong *)data0 + 2*3)[1] +
                                ((npy_ulonglong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*4)[0] =
                                ((npy_ulonglong *)data0 + 2*4)[0] +
                                ((npy_ulonglong *)data_out + 2*4)[0];
        ((npy_ulonglong *)data_out + 2*4)[1] =
                                ((npy_ulonglong *)data0 + 2*4)[1] +
                                ((npy_ulonglong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*5)[0] =
                                ((npy_ulonglong *)data0 + 2*5)[0] +
                                ((npy_ulonglong *)data_out + 2*5)[0];
        ((npy_ulonglong *)data_out + 2*5)[1] =
                                ((npy_ulonglong *)data0 + 2*5)[1] +
                                ((npy_ulonglong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*6)[0] =
                                ((npy_ulonglong *)data0 + 2*6)[0] +
                                ((npy_ulonglong *)data_out + 2*6)[0];
        ((npy_ulonglong *)data_out + 2*6)[1] =
                                ((npy_ulonglong *)data0 + 2*6)[1] +
                                ((npy_ulonglong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*7)[0] =
                                ((npy_ulonglong *)data0 + 2*7)[0] +
                                ((npy_ulonglong *)data_out + 2*7)[0];
        ((npy_ulonglong *)data_out + 2*7)[1] =
                                ((npy_ulonglong *)data0 + 2*7)[1] +
                                ((npy_ulonglong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_muladd(npy_ulonglong *data, npy_ulonglong *data_out, npy_ulonglong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u64;
    const npyv_u64 v_scalar = npyv_setall_u64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u64 b0 = npyv_loada_u64(data + vstep * 0);
            npyv_u64 c0 = npyv_loada_u64(data_out + vstep * 0);
            
#line 312
            npyv_u64 b1 = npyv_loada_u64(data + vstep * 1);
            npyv_u64 c1 = npyv_loada_u64(data_out + vstep * 1);
            
#line 312
            npyv_u64 b2 = npyv_loada_u64(data + vstep * 2);
            npyv_u64 c2 = npyv_loada_u64(data_out + vstep * 2);
            
#line 312
            npyv_u64 b3 = npyv_loada_u64(data + vstep * 3);
            npyv_u64 c3 = npyv_loada_u64(data_out + vstep * 3);
            
            #line 318
            npyv_u64 abc0 = npyv_muladd_u64(v_scalar, b0, c0);
            
#line 318
            npyv_u64 abc1 = npyv_muladd_u64(v_scalar, b1, c1);
            
#line 318
            npyv_u64 abc2 = npyv_muladd_u64(v_scalar, b2, c2);
            
#line 318
            npyv_u64 abc3 = npyv_muladd_u64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u64 b0 = npyv_load_u64(data + vstep * 0);
            npyv_u64 c0 = npyv_load_u64(data_out + vstep * 0);
            
#line 312
            npyv_u64 b1 = npyv_load_u64(data + vstep * 1);
            npyv_u64 c1 = npyv_load_u64(data_out + vstep * 1);
            
#line 312
            npyv_u64 b2 = npyv_load_u64(data + vstep * 2);
            npyv_u64 c2 = npyv_load_u64(data_out + vstep * 2);
            
#line 312
            npyv_u64 b3 = npyv_load_u64(data + vstep * 3);
            npyv_u64 c3 = npyv_load_u64(data_out + vstep * 3);
            
            #line 318
            npyv_u64 abc0 = npyv_muladd_u64(v_scalar, b0, c0);
            
#line 318
            npyv_u64 abc1 = npyv_muladd_u64(v_scalar, b1, c1);
            
#line 318
            npyv_u64 abc2 = npyv_muladd_u64(v_scalar, b2, c2);
            
#line 318
            npyv_u64 abc3 = npyv_muladd_u64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data, count);
        npyv_u64 b = npyv_load_tillz_u64(data_out, count);
        npyv_store_till_u64(data_out, count, npyv_muladd_u64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ulonglong b0 = (data[0]);
        const npy_ulonglong c0 = (data_out[0]);
        
#line 340
        const npy_ulonglong b1 = (data[1]);
        const npy_ulonglong c1 = (data_out[1]);
        
#line 340
        const npy_ulonglong b2 = (data[2]);
        const npy_ulonglong c2 = (data_out[2]);
        
#line 340
        const npy_ulonglong b3 = (data[3]);
        const npy_ulonglong c3 = (data_out[3]);
        
        #line 346
        const npy_ulonglong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ulonglong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ulonglong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ulonglong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ulonglong b = (*data);
        const npy_ulonglong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ulonglong
}

static void
ulonglong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ulonglong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u64 a0 = npyv_loada_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_loada_u64(data1 + vstep * 0);
            npyv_u64 c0 = npyv_loada_u64(data_out + vstep * 0);
            
#line 390
            npyv_u64 a1 = npyv_loada_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_loada_u64(data1 + vstep * 1);
            npyv_u64 c1 = npyv_loada_u64(data_out + vstep * 1);
            
#line 390
            npyv_u64 a2 = npyv_loada_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_loada_u64(data1 + vstep * 2);
            npyv_u64 c2 = npyv_loada_u64(data_out + vstep * 2);
            
#line 390
            npyv_u64 a3 = npyv_loada_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_loada_u64(data1 + vstep * 3);
            npyv_u64 c3 = npyv_loada_u64(data_out + vstep * 3);
            
            #line 397
            npyv_u64 abc0 = npyv_muladd_u64(a0, b0, c0);
            
#line 397
            npyv_u64 abc1 = npyv_muladd_u64(a1, b1, c1);
            
#line 397
            npyv_u64 abc2 = npyv_muladd_u64(a2, b2, c2);
            
#line 397
            npyv_u64 abc3 = npyv_muladd_u64(a3, b3, c3);
            
            #line 402
            npyv_storea_u64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u64 a0 = npyv_load_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_load_u64(data1 + vstep * 0);
            npyv_u64 c0 = npyv_load_u64(data_out + vstep * 0);
            
#line 390
            npyv_u64 a1 = npyv_load_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_load_u64(data1 + vstep * 1);
            npyv_u64 c1 = npyv_load_u64(data_out + vstep * 1);
            
#line 390
            npyv_u64 a2 = npyv_load_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_load_u64(data1 + vstep * 2);
            npyv_u64 c2 = npyv_load_u64(data_out + vstep * 2);
            
#line 390
            npyv_u64 a3 = npyv_load_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_load_u64(data1 + vstep * 3);
            npyv_u64 c3 = npyv_load_u64(data_out + vstep * 3);
            
            #line 397
            npyv_u64 abc0 = npyv_muladd_u64(a0, b0, c0);
            
#line 397
            npyv_u64 abc1 = npyv_muladd_u64(a1, b1, c1);
            
#line 397
            npyv_u64 abc2 = npyv_muladd_u64(a2, b2, c2);
            
#line 397
            npyv_u64 abc3 = npyv_muladd_u64(a3, b3, c3);
            
            #line 402
            npyv_store_u64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data0, count);
        npyv_u64 b = npyv_load_tillz_u64(data1, count);
        npyv_u64 c = npyv_load_tillz_u64(data_out, count);
        npyv_store_till_u64(data_out, count, npyv_muladd_u64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ulonglong a0 = (data0[0]);
        const npy_ulonglong b0 = (data1[0]);
        const npy_ulonglong c0 = (data_out[0]);
        
#line 420
        const npy_ulonglong a1 = (data0[1]);
        const npy_ulonglong b1 = (data1[1]);
        const npy_ulonglong c1 = (data_out[1]);
        
#line 420
        const npy_ulonglong a2 = (data0[2]);
        const npy_ulonglong b2 = (data1[2]);
        const npy_ulonglong c2 = (data_out[2]);
        
#line 420
        const npy_ulonglong a3 = (data0[3]);
        const npy_ulonglong b3 = (data1[3]);
        const npy_ulonglong c3 = (data_out[3]);
        
        #line 427
        const npy_ulonglong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ulonglong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ulonglong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ulonglong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ulonglong a = (*data0);
        const npy_ulonglong b = (*data1);
        const npy_ulonglong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ulonglong

}

/* Some extra specializations for the two operand case */
static void
ulonglong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong value0 = (*(npy_ulonglong *)dataptr[0]);
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ulonglong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ulonglong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong value1 = (*(npy_ulonglong *)dataptr[1]);
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ulonglong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong accum = 0;

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u64;
    npyv_u64 v_accum = npyv_zero_u64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u64 a0 = npyv_loada_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_loada_u64(data1 + vstep * 0);
            
#line 501
            npyv_u64 a1 = npyv_loada_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_loada_u64(data1 + vstep * 1);
            
#line 501
            npyv_u64 a2 = npyv_loada_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_loada_u64(data1 + vstep * 2);
            
#line 501
            npyv_u64 a3 = npyv_loada_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_loada_u64(data1 + vstep * 3);
            
            npyv_u64 ab3 = npyv_muladd_u64(a3, b3, v_accum);
            npyv_u64 ab2 = npyv_muladd_u64(a2, b2, ab3);
            npyv_u64 ab1 = npyv_muladd_u64(a1, b1, ab2);
                   v_accum = npyv_muladd_u64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u64 a0 = npyv_load_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_load_u64(data1 + vstep * 0);
            
#line 501
            npyv_u64 a1 = npyv_load_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_load_u64(data1 + vstep * 1);
            
#line 501
            npyv_u64 a2 = npyv_load_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_load_u64(data1 + vstep * 2);
            
#line 501
            npyv_u64 a3 = npyv_load_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_load_u64(data1 + vstep * 3);
            
            npyv_u64 ab3 = npyv_muladd_u64(a3, b3, v_accum);
            npyv_u64 ab2 = npyv_muladd_u64(a2, b2, ab3);
            npyv_u64 ab1 = npyv_muladd_u64(a1, b1, ab2);
                   v_accum = npyv_muladd_u64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data0, count);
        npyv_u64 b = npyv_load_tillz_u64(data1, count);
        v_accum = npyv_muladd_u64(a, b, v_accum);
    }
    accum = npyv_sum_u64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ulonglong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ulonglong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ulonglong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ulonglong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ulonglong a = (*data0);
        const npy_ulonglong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ulonglong
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong value0 = (*(npy_ulonglong *)dataptr[0]);
    npy_ulonglong accum = ulonglong_sum_of_arr(data1, count);
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong value1 = (*(npy_ulonglong *)dataptr[1]);
    npy_ulonglong accum = ulonglong_sum_of_arr(data0, count);
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
ulonglong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data2 = (npy_ulonglong *)dataptr[2];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
ulonglong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        *(npy_ulonglong *)dataptr[nop] = (temp +
                                           (*(npy_ulonglong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ulonglong);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ulonglong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ulonglong *data = (npy_ulonglong *)dataptr[0];
    npy_ulonglong accum = ulonglong_sum_of_arr(data, count);
    *((npy_ulonglong *)dataptr[1]) = (accum + (*((npy_ulonglong *)dataptr[1])));
#else
    npy_ulonglong accum_re = 0, accum_im = 0;
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ulonglong re01 = data0[0] + data0[2];
        const npy_ulonglong re23 = data0[4] + data0[6];
        const npy_ulonglong im13 = data0[1] + data0[3];
        const npy_ulonglong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ulonglong *)dataptr[1])[0] += accum_re;
    ((npy_ulonglong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
ulonglong_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ulonglong accum_re = 0, accum_im = 0;
#else
    npy_ulonglong accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_ulonglong *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_ulonglong *)data0) *
                 (*(npy_ulonglong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_ulonglong *)data0) *
                 (*(npy_ulonglong *)data1) *
                 (*(npy_ulonglong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_ulonglong *)data0)[0];
        accum_im += ((npy_ulonglong *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_ulonglong *)dataptr[3])[0] += accum_re;
    ((npy_ulonglong *)dataptr[3])[1] += accum_im;
#  else
    ((npy_ulonglong *)dataptr[nop])[0] += accum_re;
    ((npy_ulonglong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_ulonglong *)dataptr[3]) = (accum +
                                    (*((npy_ulonglong *)dataptr[3])));
#  else
    *((npy_ulonglong *)dataptr[nop]) = (accum +
                                    (*((npy_ulonglong *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
ulonglong_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) *
                                         (*(npy_ulonglong *)data1) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_ulonglong *)data_out = ((*(npy_ulonglong *)data0) *
                                         (*(npy_ulonglong *)data1) *
                                         (*(npy_ulonglong *)data2) +
                                         (*(npy_ulonglong *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        *(npy_ulonglong *)dataptr[nop] = (temp +
                                           (*(npy_ulonglong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_ulonglong *)data_out)[0] = ((npy_ulonglong *)data0)[0] +
                                         ((npy_ulonglong *)data_out)[0];
        ((npy_ulonglong *)data_out)[1] = ((npy_ulonglong *)data0)[1] +
                                         ((npy_ulonglong *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
ulonglong_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_ulonglong *)data_out + 2*6)[0] =
                                    ((npy_ulonglong *)data0 + 2*6)[0] +
                                    ((npy_ulonglong *)data_out + 2*6)[0];
            ((npy_ulonglong *)data_out + 2*6)[1] =
                                    ((npy_ulonglong *)data0 + 2*6)[1] +
                                    ((npy_ulonglong *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_ulonglong *)data_out + 2*5)[0] =
                                    ((npy_ulonglong *)data0 + 2*5)[0] +
                                    ((npy_ulonglong *)data_out + 2*5)[0];
            ((npy_ulonglong *)data_out + 2*5)[1] =
                                    ((npy_ulonglong *)data0 + 2*5)[1] +
                                    ((npy_ulonglong *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_ulonglong *)data_out + 2*4)[0] =
                                    ((npy_ulonglong *)data0 + 2*4)[0] +
                                    ((npy_ulonglong *)data_out + 2*4)[0];
            ((npy_ulonglong *)data_out + 2*4)[1] =
                                    ((npy_ulonglong *)data0 + 2*4)[1] +
                                    ((npy_ulonglong *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_ulonglong *)data_out + 2*3)[0] =
                                    ((npy_ulonglong *)data0 + 2*3)[0] +
                                    ((npy_ulonglong *)data_out + 2*3)[0];
            ((npy_ulonglong *)data_out + 2*3)[1] =
                                    ((npy_ulonglong *)data0 + 2*3)[1] +
                                    ((npy_ulonglong *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_ulonglong *)data_out + 2*2)[0] =
                                    ((npy_ulonglong *)data0 + 2*2)[0] +
                                    ((npy_ulonglong *)data_out + 2*2)[0];
            ((npy_ulonglong *)data_out + 2*2)[1] =
                                    ((npy_ulonglong *)data0 + 2*2)[1] +
                                    ((npy_ulonglong *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_ulonglong *)data_out + 2*1)[0] =
                                    ((npy_ulonglong *)data0 + 2*1)[0] +
                                    ((npy_ulonglong *)data_out + 2*1)[0];
            ((npy_ulonglong *)data_out + 2*1)[1] =
                                    ((npy_ulonglong *)data0 + 2*1)[1] +
                                    ((npy_ulonglong *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_ulonglong *)data_out + 2*0)[0] =
                                    ((npy_ulonglong *)data0 + 2*0)[0] +
                                    ((npy_ulonglong *)data_out + 2*0)[0];
            ((npy_ulonglong *)data_out + 2*0)[1] =
                                    ((npy_ulonglong *)data0 + 2*0)[1] +
                                    ((npy_ulonglong *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*0)[0] =
                                ((npy_ulonglong *)data0 + 2*0)[0] +
                                ((npy_ulonglong *)data_out + 2*0)[0];
        ((npy_ulonglong *)data_out + 2*0)[1] =
                                ((npy_ulonglong *)data0 + 2*0)[1] +
                                ((npy_ulonglong *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*1)[0] =
                                ((npy_ulonglong *)data0 + 2*1)[0] +
                                ((npy_ulonglong *)data_out + 2*1)[0];
        ((npy_ulonglong *)data_out + 2*1)[1] =
                                ((npy_ulonglong *)data0 + 2*1)[1] +
                                ((npy_ulonglong *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*2)[0] =
                                ((npy_ulonglong *)data0 + 2*2)[0] +
                                ((npy_ulonglong *)data_out + 2*2)[0];
        ((npy_ulonglong *)data_out + 2*2)[1] =
                                ((npy_ulonglong *)data0 + 2*2)[1] +
                                ((npy_ulonglong *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*3)[0] =
                                ((npy_ulonglong *)data0 + 2*3)[0] +
                                ((npy_ulonglong *)data_out + 2*3)[0];
        ((npy_ulonglong *)data_out + 2*3)[1] =
                                ((npy_ulonglong *)data0 + 2*3)[1] +
                                ((npy_ulonglong *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*4)[0] =
                                ((npy_ulonglong *)data0 + 2*4)[0] +
                                ((npy_ulonglong *)data_out + 2*4)[0];
        ((npy_ulonglong *)data_out + 2*4)[1] =
                                ((npy_ulonglong *)data0 + 2*4)[1] +
                                ((npy_ulonglong *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*5)[0] =
                                ((npy_ulonglong *)data0 + 2*5)[0] +
                                ((npy_ulonglong *)data_out + 2*5)[0];
        ((npy_ulonglong *)data_out + 2*5)[1] =
                                ((npy_ulonglong *)data0 + 2*5)[1] +
                                ((npy_ulonglong *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*6)[0] =
                                ((npy_ulonglong *)data0 + 2*6)[0] +
                                ((npy_ulonglong *)data_out + 2*6)[0];
        ((npy_ulonglong *)data_out + 2*6)[1] =
                                ((npy_ulonglong *)data0 + 2*6)[1] +
                                ((npy_ulonglong *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_ulonglong *)data_out + 2*7)[0] =
                                ((npy_ulonglong *)data0 + 2*7)[0] +
                                ((npy_ulonglong *)data_out + 2*7)[0];
        ((npy_ulonglong *)data_out + 2*7)[1] =
                                ((npy_ulonglong *)data0 + 2*7)[1] +
                                ((npy_ulonglong *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_muladd(npy_ulonglong *data, npy_ulonglong *data_out, npy_ulonglong scalar, npy_intp count)
{
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u64;
    const npyv_u64 v_scalar = npyv_setall_u64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u64 b0 = npyv_loada_u64(data + vstep * 0);
            npyv_u64 c0 = npyv_loada_u64(data_out + vstep * 0);
            
#line 312
            npyv_u64 b1 = npyv_loada_u64(data + vstep * 1);
            npyv_u64 c1 = npyv_loada_u64(data_out + vstep * 1);
            
#line 312
            npyv_u64 b2 = npyv_loada_u64(data + vstep * 2);
            npyv_u64 c2 = npyv_loada_u64(data_out + vstep * 2);
            
#line 312
            npyv_u64 b3 = npyv_loada_u64(data + vstep * 3);
            npyv_u64 c3 = npyv_loada_u64(data_out + vstep * 3);
            
            #line 318
            npyv_u64 abc0 = npyv_muladd_u64(v_scalar, b0, c0);
            
#line 318
            npyv_u64 abc1 = npyv_muladd_u64(v_scalar, b1, c1);
            
#line 318
            npyv_u64 abc2 = npyv_muladd_u64(v_scalar, b2, c2);
            
#line 318
            npyv_u64 abc3 = npyv_muladd_u64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_u64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_u64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_u64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_u64 b0 = npyv_load_u64(data + vstep * 0);
            npyv_u64 c0 = npyv_load_u64(data_out + vstep * 0);
            
#line 312
            npyv_u64 b1 = npyv_load_u64(data + vstep * 1);
            npyv_u64 c1 = npyv_load_u64(data_out + vstep * 1);
            
#line 312
            npyv_u64 b2 = npyv_load_u64(data + vstep * 2);
            npyv_u64 c2 = npyv_load_u64(data_out + vstep * 2);
            
#line 312
            npyv_u64 b3 = npyv_load_u64(data + vstep * 3);
            npyv_u64 c3 = npyv_load_u64(data_out + vstep * 3);
            
            #line 318
            npyv_u64 abc0 = npyv_muladd_u64(v_scalar, b0, c0);
            
#line 318
            npyv_u64 abc1 = npyv_muladd_u64(v_scalar, b1, c1);
            
#line 318
            npyv_u64 abc2 = npyv_muladd_u64(v_scalar, b2, c2);
            
#line 318
            npyv_u64 abc3 = npyv_muladd_u64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_u64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_u64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_u64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data, count);
        npyv_u64 b = npyv_load_tillz_u64(data_out, count);
        npyv_store_till_u64(data_out, count, npyv_muladd_u64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_ulonglong b0 = (data[0]);
        const npy_ulonglong c0 = (data_out[0]);
        
#line 340
        const npy_ulonglong b1 = (data[1]);
        const npy_ulonglong c1 = (data_out[1]);
        
#line 340
        const npy_ulonglong b2 = (data[2]);
        const npy_ulonglong c2 = (data_out[2]);
        
#line 340
        const npy_ulonglong b3 = (data[3]);
        const npy_ulonglong c3 = (data_out[3]);
        
        #line 346
        const npy_ulonglong abc0 = scalar * b0 + c0;
        
#line 346
        const npy_ulonglong abc1 = scalar * b1 + c1;
        
#line 346
        const npy_ulonglong abc2 = scalar * b2 + c2;
        
#line 346
        const npy_ulonglong abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_ulonglong b = (*data);
        const npy_ulonglong c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_ulonglong
}

static void
ulonglong_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_ulonglong
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_u64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u64 a0 = npyv_loada_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_loada_u64(data1 + vstep * 0);
            npyv_u64 c0 = npyv_loada_u64(data_out + vstep * 0);
            
#line 390
            npyv_u64 a1 = npyv_loada_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_loada_u64(data1 + vstep * 1);
            npyv_u64 c1 = npyv_loada_u64(data_out + vstep * 1);
            
#line 390
            npyv_u64 a2 = npyv_loada_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_loada_u64(data1 + vstep * 2);
            npyv_u64 c2 = npyv_loada_u64(data_out + vstep * 2);
            
#line 390
            npyv_u64 a3 = npyv_loada_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_loada_u64(data1 + vstep * 3);
            npyv_u64 c3 = npyv_loada_u64(data_out + vstep * 3);
            
            #line 397
            npyv_u64 abc0 = npyv_muladd_u64(a0, b0, c0);
            
#line 397
            npyv_u64 abc1 = npyv_muladd_u64(a1, b1, c1);
            
#line 397
            npyv_u64 abc2 = npyv_muladd_u64(a2, b2, c2);
            
#line 397
            npyv_u64 abc3 = npyv_muladd_u64(a3, b3, c3);
            
            #line 402
            npyv_storea_u64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_u64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_u64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_u64 a0 = npyv_load_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_load_u64(data1 + vstep * 0);
            npyv_u64 c0 = npyv_load_u64(data_out + vstep * 0);
            
#line 390
            npyv_u64 a1 = npyv_load_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_load_u64(data1 + vstep * 1);
            npyv_u64 c1 = npyv_load_u64(data_out + vstep * 1);
            
#line 390
            npyv_u64 a2 = npyv_load_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_load_u64(data1 + vstep * 2);
            npyv_u64 c2 = npyv_load_u64(data_out + vstep * 2);
            
#line 390
            npyv_u64 a3 = npyv_load_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_load_u64(data1 + vstep * 3);
            npyv_u64 c3 = npyv_load_u64(data_out + vstep * 3);
            
            #line 397
            npyv_u64 abc0 = npyv_muladd_u64(a0, b0, c0);
            
#line 397
            npyv_u64 abc1 = npyv_muladd_u64(a1, b1, c1);
            
#line 397
            npyv_u64 abc2 = npyv_muladd_u64(a2, b2, c2);
            
#line 397
            npyv_u64 abc3 = npyv_muladd_u64(a3, b3, c3);
            
            #line 402
            npyv_store_u64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_u64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_u64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_u64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data0, count);
        npyv_u64 b = npyv_load_tillz_u64(data1, count);
        npyv_u64 c = npyv_load_tillz_u64(data_out, count);
        npyv_store_till_u64(data_out, count, npyv_muladd_u64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_ulonglong a0 = (data0[0]);
        const npy_ulonglong b0 = (data1[0]);
        const npy_ulonglong c0 = (data_out[0]);
        
#line 420
        const npy_ulonglong a1 = (data0[1]);
        const npy_ulonglong b1 = (data1[1]);
        const npy_ulonglong c1 = (data_out[1]);
        
#line 420
        const npy_ulonglong a2 = (data0[2]);
        const npy_ulonglong b2 = (data1[2]);
        const npy_ulonglong c2 = (data_out[2]);
        
#line 420
        const npy_ulonglong a3 = (data0[3]);
        const npy_ulonglong b3 = (data1[3]);
        const npy_ulonglong c3 = (data_out[3]);
        
        #line 427
        const npy_ulonglong abc0 = a0 * b0 + c0;
        
#line 427
        const npy_ulonglong abc1 = a1 * b1 + c1;
        
#line 427
        const npy_ulonglong abc2 = a2 * b2 + c2;
        
#line 427
        const npy_ulonglong abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_ulonglong a = (*data0);
        const npy_ulonglong b = (*data1);
        const npy_ulonglong c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_ulonglong

}

/* Some extra specializations for the two operand case */
static void
ulonglong_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong value0 = (*(npy_ulonglong *)dataptr[0]);
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    ulonglong_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
ulonglong_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong value1 = (*(npy_ulonglong *)dataptr[1]);
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    ulonglong_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong accum = 0;

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_ulonglong
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_u64;
    npyv_u64 v_accum = npyv_zero_u64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u64 a0 = npyv_loada_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_loada_u64(data1 + vstep * 0);
            
#line 501
            npyv_u64 a1 = npyv_loada_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_loada_u64(data1 + vstep * 1);
            
#line 501
            npyv_u64 a2 = npyv_loada_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_loada_u64(data1 + vstep * 2);
            
#line 501
            npyv_u64 a3 = npyv_loada_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_loada_u64(data1 + vstep * 3);
            
            npyv_u64 ab3 = npyv_muladd_u64(a3, b3, v_accum);
            npyv_u64 ab2 = npyv_muladd_u64(a2, b2, ab3);
            npyv_u64 ab1 = npyv_muladd_u64(a1, b1, ab2);
                   v_accum = npyv_muladd_u64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_u64 a0 = npyv_load_u64(data0 + vstep * 0);
            npyv_u64 b0 = npyv_load_u64(data1 + vstep * 0);
            
#line 501
            npyv_u64 a1 = npyv_load_u64(data0 + vstep * 1);
            npyv_u64 b1 = npyv_load_u64(data1 + vstep * 1);
            
#line 501
            npyv_u64 a2 = npyv_load_u64(data0 + vstep * 2);
            npyv_u64 b2 = npyv_load_u64(data1 + vstep * 2);
            
#line 501
            npyv_u64 a3 = npyv_load_u64(data0 + vstep * 3);
            npyv_u64 b3 = npyv_load_u64(data1 + vstep * 3);
            
            npyv_u64 ab3 = npyv_muladd_u64(a3, b3, v_accum);
            npyv_u64 ab2 = npyv_muladd_u64(a2, b2, ab3);
            npyv_u64 ab1 = npyv_muladd_u64(a1, b1, ab2);
                   v_accum = npyv_muladd_u64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_u64 a = npyv_load_tillz_u64(data0, count);
        npyv_u64 b = npyv_load_tillz_u64(data1, count);
        v_accum = npyv_muladd_u64(a, b, v_accum);
    }
    accum = npyv_sum_u64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_ulonglong ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_ulonglong ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_ulonglong ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_ulonglong ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_ulonglong a = (*data0);
        const npy_ulonglong b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_ulonglong
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong value0 = (*(npy_ulonglong *)dataptr[0]);
    npy_ulonglong accum = ulonglong_sum_of_arr(data1, count);
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong value1 = (*(npy_ulonglong *)dataptr[1]);
    npy_ulonglong accum = ulonglong_sum_of_arr(data0, count);
    *(npy_ulonglong *)dataptr[2] = ((*(npy_ulonglong *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
ulonglong_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
    npy_ulonglong *data1 = (npy_ulonglong *)dataptr[1];
    npy_ulonglong *data2 = (npy_ulonglong *)dataptr[2];
    npy_ulonglong *data_out = (npy_ulonglong *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
ulonglong_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        *(npy_ulonglong *)dataptr[nop] = (temp +
                                           (*(npy_ulonglong *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_ulonglong);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[0];
        ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_ulonglong *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_ulonglong);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
ulonglong_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_ulonglong *data = (npy_ulonglong *)dataptr[0];
    npy_ulonglong accum = ulonglong_sum_of_arr(data, count);
    *((npy_ulonglong *)dataptr[1]) = (accum + (*((npy_ulonglong *)dataptr[1])));
#else
    npy_ulonglong accum_re = 0, accum_im = 0;
    npy_ulonglong *data0 = (npy_ulonglong *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_ulonglong re01 = data0[0] + data0[2];
        const npy_ulonglong re23 = data0[4] + data0[6];
        const npy_ulonglong im13 = data0[1] + data0[3];
        const npy_ulonglong im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_ulonglong *)dataptr[1])[0] += accum_re;
    ((npy_ulonglong *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
ulonglong_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_ulonglong accum_re = 0, accum_im = 0;
#else
    npy_ulonglong accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("ulonglong_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_ulonglong *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_ulonglong *)data0) *
                 (*(npy_ulonglong *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_ulonglong *)data0) *
                 (*(npy_ulonglong *)data1) *
                 (*(npy_ulonglong *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_ulonglong temp = (*(npy_ulonglong *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_ulonglong *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_ulonglong *)data0)[0];
        accum_im += ((npy_ulonglong *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_ulonglong re, im, tmp;
        int i;
        re = ((npy_ulonglong *)dataptr[0])[0];
        im = ((npy_ulonglong *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_ulonglong *)dataptr[i])[0] -
                  im * ((npy_ulonglong *)dataptr[i])[1];
            im = re * ((npy_ulonglong *)dataptr[i])[1] +
                 im * ((npy_ulonglong *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_ulonglong *)dataptr[1000])[0] += accum_re;
    ((npy_ulonglong *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_ulonglong *)dataptr[nop])[0] += accum_re;
    ((npy_ulonglong *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_ulonglong *)dataptr[1000]) = (accum +
                                    (*((npy_ulonglong *)dataptr[1000])));
#  else
    *((npy_ulonglong *)dataptr[nop]) = (accum +
                                    (*((npy_ulonglong *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_float half_sum_of_arr(npy_half *data, npy_intp count)
{
    npy_float accum = 0;
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_half;
    npyv_half v_accum = npyv_zero_half();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_half a0 = npyv_loada_half(data + vstep * 0);
            
#line 96
            npyv_half a1 = npyv_loada_half(data + vstep * 1);
            
#line 96
            npyv_half a2 = npyv_loada_half(data + vstep * 2);
            
#line 96
            npyv_half a3 = npyv_loada_half(data + vstep * 3);
            
            npyv_half a01   = npyv_add_half(a0, a1);
            npyv_half a23   = npyv_add_half(a2, a3);
            npyv_half a0123 = npyv_add_half(a01, a23);
                     v_accum = npyv_add_half(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_half a0 = npyv_load_half(data + vstep * 0);
            
#line 96
            npyv_half a1 = npyv_load_half(data + vstep * 1);
            
#line 96
            npyv_half a2 = npyv_load_half(data + vstep * 2);
            
#line 96
            npyv_half a3 = npyv_load_half(data + vstep * 3);
            
            npyv_half a01   = npyv_add_half(a0, a1);
            npyv_half a23   = npyv_add_half(a2, a3);
            npyv_half a0123 = npyv_add_half(a01, a23);
                     v_accum = npyv_add_half(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_half a = npyv_load_tillz_half(data, count);
        v_accum = npyv_add_half(a, v_accum);
    }
    accum = npyv_sum_half(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_float a01 = npy_half_to_float(*data) + npy_half_to_float(data[1]);
        const npy_float a23 = npy_half_to_float(data[2]) + npy_half_to_float(data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += npy_half_to_float(*data);
    }
#endif // NPYV check for npy_half
    return accum;
}
#endif

#line 131
static void
half_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) *
                                         npy_half_to_float(*(npy_half *)data1) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) *
                                         npy_half_to_float(*(npy_half *)data1) *
                                         npy_half_to_float(*(npy_half *)data2) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        *(npy_half *)dataptr[nop] = npy_float_to_half(temp +
                                           npy_half_to_float(*(npy_half *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
half_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data_out = (npy_half *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) +
                                 npy_half_to_float(data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) +
                                 npy_half_to_float(data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) +
                                 npy_half_to_float(data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) +
                                 npy_half_to_float(data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) +
                                 npy_half_to_float(data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) +
                                 npy_half_to_float(data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) +
                                 npy_half_to_float(data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) +
                             npy_half_to_float(data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) +
                             npy_half_to_float(data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) +
                             npy_half_to_float(data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) +
                             npy_half_to_float(data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) +
                             npy_half_to_float(data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) +
                             npy_half_to_float(data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) +
                             npy_half_to_float(data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) +
                             npy_half_to_float(data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
half_sum_of_products_muladd(npy_half *data, npy_half *data_out, npy_float scalar, npy_intp count)
{
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_half;
    const npyv_half v_scalar = npyv_setall_half(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_half b0 = npyv_loada_half(data + vstep * 0);
            npyv_half c0 = npyv_loada_half(data_out + vstep * 0);
            
#line 312
            npyv_half b1 = npyv_loada_half(data + vstep * 1);
            npyv_half c1 = npyv_loada_half(data_out + vstep * 1);
            
#line 312
            npyv_half b2 = npyv_loada_half(data + vstep * 2);
            npyv_half c2 = npyv_loada_half(data_out + vstep * 2);
            
#line 312
            npyv_half b3 = npyv_loada_half(data + vstep * 3);
            npyv_half c3 = npyv_loada_half(data_out + vstep * 3);
            
            #line 318
            npyv_half abc0 = npyv_muladd_half(v_scalar, b0, c0);
            
#line 318
            npyv_half abc1 = npyv_muladd_half(v_scalar, b1, c1);
            
#line 318
            npyv_half abc2 = npyv_muladd_half(v_scalar, b2, c2);
            
#line 318
            npyv_half abc3 = npyv_muladd_half(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_half(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_half(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_half(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_half(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_half b0 = npyv_load_half(data + vstep * 0);
            npyv_half c0 = npyv_load_half(data_out + vstep * 0);
            
#line 312
            npyv_half b1 = npyv_load_half(data + vstep * 1);
            npyv_half c1 = npyv_load_half(data_out + vstep * 1);
            
#line 312
            npyv_half b2 = npyv_load_half(data + vstep * 2);
            npyv_half c2 = npyv_load_half(data_out + vstep * 2);
            
#line 312
            npyv_half b3 = npyv_load_half(data + vstep * 3);
            npyv_half c3 = npyv_load_half(data_out + vstep * 3);
            
            #line 318
            npyv_half abc0 = npyv_muladd_half(v_scalar, b0, c0);
            
#line 318
            npyv_half abc1 = npyv_muladd_half(v_scalar, b1, c1);
            
#line 318
            npyv_half abc2 = npyv_muladd_half(v_scalar, b2, c2);
            
#line 318
            npyv_half abc3 = npyv_muladd_half(v_scalar, b3, c3);
            
            #line 323
            npyv_store_half(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_half(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_half(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_half(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_half a = npyv_load_tillz_half(data, count);
        npyv_half b = npyv_load_tillz_half(data_out, count);
        npyv_store_till_half(data_out, count, npyv_muladd_half(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = npy_half_to_float(data[0]);
        const npy_float c0 = npy_half_to_float(data_out[0]);
        
#line 340
        const npy_float b1 = npy_half_to_float(data[1]);
        const npy_float c1 = npy_half_to_float(data_out[1]);
        
#line 340
        const npy_float b2 = npy_half_to_float(data[2]);
        const npy_float c2 = npy_half_to_float(data_out[2]);
        
#line 340
        const npy_float b3 = npy_half_to_float(data[3]);
        const npy_float c3 = npy_half_to_float(data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = npy_float_to_half(abc0);
        
#line 351
        data_out[1] = npy_float_to_half(abc1);
        
#line 351
        data_out[2] = npy_float_to_half(abc2);
        
#line 351
        data_out[3] = npy_float_to_half(abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = npy_half_to_float(*data);
        const npy_float c = npy_half_to_float(*data_out);
        *data_out = npy_float_to_half(scalar * b + c);
    }
#endif // NPYV check for npy_half
}

static void
half_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data_out = (npy_half *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_half
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_half;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_half a0 = npyv_loada_half(data0 + vstep * 0);
            npyv_half b0 = npyv_loada_half(data1 + vstep * 0);
            npyv_half c0 = npyv_loada_half(data_out + vstep * 0);
            
#line 390
            npyv_half a1 = npyv_loada_half(data0 + vstep * 1);
            npyv_half b1 = npyv_loada_half(data1 + vstep * 1);
            npyv_half c1 = npyv_loada_half(data_out + vstep * 1);
            
#line 390
            npyv_half a2 = npyv_loada_half(data0 + vstep * 2);
            npyv_half b2 = npyv_loada_half(data1 + vstep * 2);
            npyv_half c2 = npyv_loada_half(data_out + vstep * 2);
            
#line 390
            npyv_half a3 = npyv_loada_half(data0 + vstep * 3);
            npyv_half b3 = npyv_loada_half(data1 + vstep * 3);
            npyv_half c3 = npyv_loada_half(data_out + vstep * 3);
            
            #line 397
            npyv_half abc0 = npyv_muladd_half(a0, b0, c0);
            
#line 397
            npyv_half abc1 = npyv_muladd_half(a1, b1, c1);
            
#line 397
            npyv_half abc2 = npyv_muladd_half(a2, b2, c2);
            
#line 397
            npyv_half abc3 = npyv_muladd_half(a3, b3, c3);
            
            #line 402
            npyv_storea_half(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_half(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_half(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_half(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_half a0 = npyv_load_half(data0 + vstep * 0);
            npyv_half b0 = npyv_load_half(data1 + vstep * 0);
            npyv_half c0 = npyv_load_half(data_out + vstep * 0);
            
#line 390
            npyv_half a1 = npyv_load_half(data0 + vstep * 1);
            npyv_half b1 = npyv_load_half(data1 + vstep * 1);
            npyv_half c1 = npyv_load_half(data_out + vstep * 1);
            
#line 390
            npyv_half a2 = npyv_load_half(data0 + vstep * 2);
            npyv_half b2 = npyv_load_half(data1 + vstep * 2);
            npyv_half c2 = npyv_load_half(data_out + vstep * 2);
            
#line 390
            npyv_half a3 = npyv_load_half(data0 + vstep * 3);
            npyv_half b3 = npyv_load_half(data1 + vstep * 3);
            npyv_half c3 = npyv_load_half(data_out + vstep * 3);
            
            #line 397
            npyv_half abc0 = npyv_muladd_half(a0, b0, c0);
            
#line 397
            npyv_half abc1 = npyv_muladd_half(a1, b1, c1);
            
#line 397
            npyv_half abc2 = npyv_muladd_half(a2, b2, c2);
            
#line 397
            npyv_half abc3 = npyv_muladd_half(a3, b3, c3);
            
            #line 402
            npyv_store_half(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_half(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_half(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_half(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_half a = npyv_load_tillz_half(data0, count);
        npyv_half b = npyv_load_tillz_half(data1, count);
        npyv_half c = npyv_load_tillz_half(data_out, count);
        npyv_store_till_half(data_out, count, npyv_muladd_half(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = npy_half_to_float(data0[0]);
        const npy_float b0 = npy_half_to_float(data1[0]);
        const npy_float c0 = npy_half_to_float(data_out[0]);
        
#line 420
        const npy_float a1 = npy_half_to_float(data0[1]);
        const npy_float b1 = npy_half_to_float(data1[1]);
        const npy_float c1 = npy_half_to_float(data_out[1]);
        
#line 420
        const npy_float a2 = npy_half_to_float(data0[2]);
        const npy_float b2 = npy_half_to_float(data1[2]);
        const npy_float c2 = npy_half_to_float(data_out[2]);
        
#line 420
        const npy_float a3 = npy_half_to_float(data0[3]);
        const npy_float b3 = npy_half_to_float(data1[3]);
        const npy_float c3 = npy_half_to_float(data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = npy_float_to_half(abc0);
        
#line 432
        data_out[1] = npy_float_to_half(abc1);
        
#line 432
        data_out[2] = npy_float_to_half(abc2);
        
#line 432
        data_out[3] = npy_float_to_half(abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = npy_half_to_float(*data0);
        const npy_float b = npy_half_to_float(*data1);
        const npy_float c = npy_half_to_float(*data_out);
        *data_out = npy_float_to_half(a * b + c);
    }
#endif // NPYV check for npy_half

}

/* Some extra specializations for the two operand case */
static void
half_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = npy_half_to_float(*(npy_half *)dataptr[0]);
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data_out = (npy_half *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    half_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
half_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = npy_half_to_float(*(npy_half *)dataptr[1]);
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data_out = (npy_half *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    half_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_half;
    npyv_half v_accum = npyv_zero_half();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_half a0 = npyv_loada_half(data0 + vstep * 0);
            npyv_half b0 = npyv_loada_half(data1 + vstep * 0);
            
#line 501
            npyv_half a1 = npyv_loada_half(data0 + vstep * 1);
            npyv_half b1 = npyv_loada_half(data1 + vstep * 1);
            
#line 501
            npyv_half a2 = npyv_loada_half(data0 + vstep * 2);
            npyv_half b2 = npyv_loada_half(data1 + vstep * 2);
            
#line 501
            npyv_half a3 = npyv_loada_half(data0 + vstep * 3);
            npyv_half b3 = npyv_loada_half(data1 + vstep * 3);
            
            npyv_half ab3 = npyv_muladd_half(a3, b3, v_accum);
            npyv_half ab2 = npyv_muladd_half(a2, b2, ab3);
            npyv_half ab1 = npyv_muladd_half(a1, b1, ab2);
                   v_accum = npyv_muladd_half(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_half a0 = npyv_load_half(data0 + vstep * 0);
            npyv_half b0 = npyv_load_half(data1 + vstep * 0);
            
#line 501
            npyv_half a1 = npyv_load_half(data0 + vstep * 1);
            npyv_half b1 = npyv_load_half(data1 + vstep * 1);
            
#line 501
            npyv_half a2 = npyv_load_half(data0 + vstep * 2);
            npyv_half b2 = npyv_load_half(data1 + vstep * 2);
            
#line 501
            npyv_half a3 = npyv_load_half(data0 + vstep * 3);
            npyv_half b3 = npyv_load_half(data1 + vstep * 3);
            
            npyv_half ab3 = npyv_muladd_half(a3, b3, v_accum);
            npyv_half ab2 = npyv_muladd_half(a2, b2, ab3);
            npyv_half ab1 = npyv_muladd_half(a1, b1, ab2);
                   v_accum = npyv_muladd_half(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_half a = npyv_load_tillz_half(data0, count);
        npyv_half b = npyv_load_tillz_half(data1, count);
        v_accum = npyv_muladd_half(a, b, v_accum);
    }
    accum = npyv_sum_half(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = npy_half_to_float(data0[0]) * npy_half_to_float(data1[0]);
        
#line 524
        const npy_float ab1 = npy_half_to_float(data0[1]) * npy_half_to_float(data1[1]);
        
#line 524
        const npy_float ab2 = npy_half_to_float(data0[2]) * npy_half_to_float(data1[2]);
        
#line 524
        const npy_float ab3 = npy_half_to_float(data0[3]) * npy_half_to_float(data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = npy_half_to_float(*data0);
        const npy_float b = npy_half_to_float(*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_half
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_float value0 = npy_half_to_float(*(npy_half *)dataptr[0]);
    npy_float accum = half_sum_of_arr(data1, count);
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_float value1 = npy_half_to_float(*(npy_half *)dataptr[1]);
    npy_float accum = half_sum_of_arr(data0, count);
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
half_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data2 = (npy_half *)dataptr[2];
    npy_half *data_out = (npy_half *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) *
                             npy_half_to_float(data1[0]) *
                             npy_half_to_float(data2[0]) +
                             npy_half_to_float(data_out[0]));

#line 576
        data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) *
                             npy_half_to_float(data1[1]) *
                             npy_half_to_float(data2[1]) +
                             npy_half_to_float(data_out[1]));

#line 576
        data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) *
                             npy_half_to_float(data1[2]) *
                             npy_half_to_float(data2[2]) +
                             npy_half_to_float(data_out[2]));

#line 576
        data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) *
                             npy_half_to_float(data1[3]) *
                             npy_half_to_float(data2[3]) +
                             npy_half_to_float(data_out[3]));

#line 576
        data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) *
                             npy_half_to_float(data1[4]) *
                             npy_half_to_float(data2[4]) +
                             npy_half_to_float(data_out[4]));

#line 576
        data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) *
                             npy_half_to_float(data1[5]) *
                             npy_half_to_float(data2[5]) +
                             npy_half_to_float(data_out[5]));

#line 576
        data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) *
                             npy_half_to_float(data1[6]) *
                             npy_half_to_float(data2[6]) +
                             npy_half_to_float(data_out[6]));

#line 576
        data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) *
                             npy_half_to_float(data1[7]) *
                             npy_half_to_float(data2[7]) +
                             npy_half_to_float(data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) *
                         npy_half_to_float(data1[0]) *
                         npy_half_to_float(data2[0]) +
                         npy_half_to_float(data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) *
                         npy_half_to_float(data1[1]) *
                         npy_half_to_float(data2[1]) +
                         npy_half_to_float(data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) *
                         npy_half_to_float(data1[2]) *
                         npy_half_to_float(data2[2]) +
                         npy_half_to_float(data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) *
                         npy_half_to_float(data1[3]) *
                         npy_half_to_float(data2[3]) +
                         npy_half_to_float(data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) *
                         npy_half_to_float(data1[4]) *
                         npy_half_to_float(data2[4]) +
                         npy_half_to_float(data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) *
                         npy_half_to_float(data1[5]) *
                         npy_half_to_float(data2[5]) +
                         npy_half_to_float(data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) *
                         npy_half_to_float(data1[6]) *
                         npy_half_to_float(data2[6]) +
                         npy_half_to_float(data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) *
                         npy_half_to_float(data1[7]) *
                         npy_half_to_float(data2[7]) +
                         npy_half_to_float(data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
half_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        *(npy_half *)dataptr[nop] = npy_float_to_half(temp +
                                           npy_half_to_float(*(npy_half *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_half);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_half);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_half *data = (npy_half *)dataptr[0];
    npy_float accum = half_sum_of_arr(data, count);
    *((npy_half *)dataptr[1]) = npy_float_to_half(accum + npy_half_to_float(*((npy_half *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
half_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += npy_half_to_float(*(npy_half *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += npy_half_to_float(*(npy_half *)data0) *
                 npy_half_to_float(*(npy_half *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += npy_half_to_float(*(npy_half *)data0) *
                 npy_half_to_float(*(npy_half *)data1) *
                 npy_half_to_float(*(npy_half *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_half *)dataptr[1]) = npy_float_to_half(accum +
                                    npy_half_to_float(*((npy_half *)dataptr[1])));
#  else
    *((npy_half *)dataptr[nop]) = npy_float_to_half(accum +
                                    npy_half_to_float(*((npy_half *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
half_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) *
                                         npy_half_to_float(*(npy_half *)data1) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) *
                                         npy_half_to_float(*(npy_half *)data1) *
                                         npy_half_to_float(*(npy_half *)data2) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        *(npy_half *)dataptr[nop] = npy_float_to_half(temp +
                                           npy_half_to_float(*(npy_half *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
half_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data_out = (npy_half *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) +
                                 npy_half_to_float(data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) +
                                 npy_half_to_float(data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) +
                                 npy_half_to_float(data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) +
                                 npy_half_to_float(data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) +
                                 npy_half_to_float(data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) +
                                 npy_half_to_float(data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) +
                                 npy_half_to_float(data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) +
                             npy_half_to_float(data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) +
                             npy_half_to_float(data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) +
                             npy_half_to_float(data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) +
                             npy_half_to_float(data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) +
                             npy_half_to_float(data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) +
                             npy_half_to_float(data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) +
                             npy_half_to_float(data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) +
                             npy_half_to_float(data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
half_sum_of_products_muladd(npy_half *data, npy_half *data_out, npy_float scalar, npy_intp count)
{
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_half;
    const npyv_half v_scalar = npyv_setall_half(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_half b0 = npyv_loada_half(data + vstep * 0);
            npyv_half c0 = npyv_loada_half(data_out + vstep * 0);
            
#line 312
            npyv_half b1 = npyv_loada_half(data + vstep * 1);
            npyv_half c1 = npyv_loada_half(data_out + vstep * 1);
            
#line 312
            npyv_half b2 = npyv_loada_half(data + vstep * 2);
            npyv_half c2 = npyv_loada_half(data_out + vstep * 2);
            
#line 312
            npyv_half b3 = npyv_loada_half(data + vstep * 3);
            npyv_half c3 = npyv_loada_half(data_out + vstep * 3);
            
            #line 318
            npyv_half abc0 = npyv_muladd_half(v_scalar, b0, c0);
            
#line 318
            npyv_half abc1 = npyv_muladd_half(v_scalar, b1, c1);
            
#line 318
            npyv_half abc2 = npyv_muladd_half(v_scalar, b2, c2);
            
#line 318
            npyv_half abc3 = npyv_muladd_half(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_half(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_half(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_half(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_half(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_half b0 = npyv_load_half(data + vstep * 0);
            npyv_half c0 = npyv_load_half(data_out + vstep * 0);
            
#line 312
            npyv_half b1 = npyv_load_half(data + vstep * 1);
            npyv_half c1 = npyv_load_half(data_out + vstep * 1);
            
#line 312
            npyv_half b2 = npyv_load_half(data + vstep * 2);
            npyv_half c2 = npyv_load_half(data_out + vstep * 2);
            
#line 312
            npyv_half b3 = npyv_load_half(data + vstep * 3);
            npyv_half c3 = npyv_load_half(data_out + vstep * 3);
            
            #line 318
            npyv_half abc0 = npyv_muladd_half(v_scalar, b0, c0);
            
#line 318
            npyv_half abc1 = npyv_muladd_half(v_scalar, b1, c1);
            
#line 318
            npyv_half abc2 = npyv_muladd_half(v_scalar, b2, c2);
            
#line 318
            npyv_half abc3 = npyv_muladd_half(v_scalar, b3, c3);
            
            #line 323
            npyv_store_half(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_half(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_half(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_half(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_half a = npyv_load_tillz_half(data, count);
        npyv_half b = npyv_load_tillz_half(data_out, count);
        npyv_store_till_half(data_out, count, npyv_muladd_half(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = npy_half_to_float(data[0]);
        const npy_float c0 = npy_half_to_float(data_out[0]);
        
#line 340
        const npy_float b1 = npy_half_to_float(data[1]);
        const npy_float c1 = npy_half_to_float(data_out[1]);
        
#line 340
        const npy_float b2 = npy_half_to_float(data[2]);
        const npy_float c2 = npy_half_to_float(data_out[2]);
        
#line 340
        const npy_float b3 = npy_half_to_float(data[3]);
        const npy_float c3 = npy_half_to_float(data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = npy_float_to_half(abc0);
        
#line 351
        data_out[1] = npy_float_to_half(abc1);
        
#line 351
        data_out[2] = npy_float_to_half(abc2);
        
#line 351
        data_out[3] = npy_float_to_half(abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = npy_half_to_float(*data);
        const npy_float c = npy_half_to_float(*data_out);
        *data_out = npy_float_to_half(scalar * b + c);
    }
#endif // NPYV check for npy_half
}

static void
half_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data_out = (npy_half *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_half
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_half;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_half a0 = npyv_loada_half(data0 + vstep * 0);
            npyv_half b0 = npyv_loada_half(data1 + vstep * 0);
            npyv_half c0 = npyv_loada_half(data_out + vstep * 0);
            
#line 390
            npyv_half a1 = npyv_loada_half(data0 + vstep * 1);
            npyv_half b1 = npyv_loada_half(data1 + vstep * 1);
            npyv_half c1 = npyv_loada_half(data_out + vstep * 1);
            
#line 390
            npyv_half a2 = npyv_loada_half(data0 + vstep * 2);
            npyv_half b2 = npyv_loada_half(data1 + vstep * 2);
            npyv_half c2 = npyv_loada_half(data_out + vstep * 2);
            
#line 390
            npyv_half a3 = npyv_loada_half(data0 + vstep * 3);
            npyv_half b3 = npyv_loada_half(data1 + vstep * 3);
            npyv_half c3 = npyv_loada_half(data_out + vstep * 3);
            
            #line 397
            npyv_half abc0 = npyv_muladd_half(a0, b0, c0);
            
#line 397
            npyv_half abc1 = npyv_muladd_half(a1, b1, c1);
            
#line 397
            npyv_half abc2 = npyv_muladd_half(a2, b2, c2);
            
#line 397
            npyv_half abc3 = npyv_muladd_half(a3, b3, c3);
            
            #line 402
            npyv_storea_half(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_half(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_half(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_half(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_half a0 = npyv_load_half(data0 + vstep * 0);
            npyv_half b0 = npyv_load_half(data1 + vstep * 0);
            npyv_half c0 = npyv_load_half(data_out + vstep * 0);
            
#line 390
            npyv_half a1 = npyv_load_half(data0 + vstep * 1);
            npyv_half b1 = npyv_load_half(data1 + vstep * 1);
            npyv_half c1 = npyv_load_half(data_out + vstep * 1);
            
#line 390
            npyv_half a2 = npyv_load_half(data0 + vstep * 2);
            npyv_half b2 = npyv_load_half(data1 + vstep * 2);
            npyv_half c2 = npyv_load_half(data_out + vstep * 2);
            
#line 390
            npyv_half a3 = npyv_load_half(data0 + vstep * 3);
            npyv_half b3 = npyv_load_half(data1 + vstep * 3);
            npyv_half c3 = npyv_load_half(data_out + vstep * 3);
            
            #line 397
            npyv_half abc0 = npyv_muladd_half(a0, b0, c0);
            
#line 397
            npyv_half abc1 = npyv_muladd_half(a1, b1, c1);
            
#line 397
            npyv_half abc2 = npyv_muladd_half(a2, b2, c2);
            
#line 397
            npyv_half abc3 = npyv_muladd_half(a3, b3, c3);
            
            #line 402
            npyv_store_half(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_half(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_half(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_half(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_half a = npyv_load_tillz_half(data0, count);
        npyv_half b = npyv_load_tillz_half(data1, count);
        npyv_half c = npyv_load_tillz_half(data_out, count);
        npyv_store_till_half(data_out, count, npyv_muladd_half(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = npy_half_to_float(data0[0]);
        const npy_float b0 = npy_half_to_float(data1[0]);
        const npy_float c0 = npy_half_to_float(data_out[0]);
        
#line 420
        const npy_float a1 = npy_half_to_float(data0[1]);
        const npy_float b1 = npy_half_to_float(data1[1]);
        const npy_float c1 = npy_half_to_float(data_out[1]);
        
#line 420
        const npy_float a2 = npy_half_to_float(data0[2]);
        const npy_float b2 = npy_half_to_float(data1[2]);
        const npy_float c2 = npy_half_to_float(data_out[2]);
        
#line 420
        const npy_float a3 = npy_half_to_float(data0[3]);
        const npy_float b3 = npy_half_to_float(data1[3]);
        const npy_float c3 = npy_half_to_float(data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = npy_float_to_half(abc0);
        
#line 432
        data_out[1] = npy_float_to_half(abc1);
        
#line 432
        data_out[2] = npy_float_to_half(abc2);
        
#line 432
        data_out[3] = npy_float_to_half(abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = npy_half_to_float(*data0);
        const npy_float b = npy_half_to_float(*data1);
        const npy_float c = npy_half_to_float(*data_out);
        *data_out = npy_float_to_half(a * b + c);
    }
#endif // NPYV check for npy_half

}

/* Some extra specializations for the two operand case */
static void
half_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = npy_half_to_float(*(npy_half *)dataptr[0]);
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data_out = (npy_half *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    half_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
half_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = npy_half_to_float(*(npy_half *)dataptr[1]);
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data_out = (npy_half *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    half_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_half;
    npyv_half v_accum = npyv_zero_half();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_half a0 = npyv_loada_half(data0 + vstep * 0);
            npyv_half b0 = npyv_loada_half(data1 + vstep * 0);
            
#line 501
            npyv_half a1 = npyv_loada_half(data0 + vstep * 1);
            npyv_half b1 = npyv_loada_half(data1 + vstep * 1);
            
#line 501
            npyv_half a2 = npyv_loada_half(data0 + vstep * 2);
            npyv_half b2 = npyv_loada_half(data1 + vstep * 2);
            
#line 501
            npyv_half a3 = npyv_loada_half(data0 + vstep * 3);
            npyv_half b3 = npyv_loada_half(data1 + vstep * 3);
            
            npyv_half ab3 = npyv_muladd_half(a3, b3, v_accum);
            npyv_half ab2 = npyv_muladd_half(a2, b2, ab3);
            npyv_half ab1 = npyv_muladd_half(a1, b1, ab2);
                   v_accum = npyv_muladd_half(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_half a0 = npyv_load_half(data0 + vstep * 0);
            npyv_half b0 = npyv_load_half(data1 + vstep * 0);
            
#line 501
            npyv_half a1 = npyv_load_half(data0 + vstep * 1);
            npyv_half b1 = npyv_load_half(data1 + vstep * 1);
            
#line 501
            npyv_half a2 = npyv_load_half(data0 + vstep * 2);
            npyv_half b2 = npyv_load_half(data1 + vstep * 2);
            
#line 501
            npyv_half a3 = npyv_load_half(data0 + vstep * 3);
            npyv_half b3 = npyv_load_half(data1 + vstep * 3);
            
            npyv_half ab3 = npyv_muladd_half(a3, b3, v_accum);
            npyv_half ab2 = npyv_muladd_half(a2, b2, ab3);
            npyv_half ab1 = npyv_muladd_half(a1, b1, ab2);
                   v_accum = npyv_muladd_half(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_half a = npyv_load_tillz_half(data0, count);
        npyv_half b = npyv_load_tillz_half(data1, count);
        v_accum = npyv_muladd_half(a, b, v_accum);
    }
    accum = npyv_sum_half(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = npy_half_to_float(data0[0]) * npy_half_to_float(data1[0]);
        
#line 524
        const npy_float ab1 = npy_half_to_float(data0[1]) * npy_half_to_float(data1[1]);
        
#line 524
        const npy_float ab2 = npy_half_to_float(data0[2]) * npy_half_to_float(data1[2]);
        
#line 524
        const npy_float ab3 = npy_half_to_float(data0[3]) * npy_half_to_float(data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = npy_half_to_float(*data0);
        const npy_float b = npy_half_to_float(*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_half
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_float value0 = npy_half_to_float(*(npy_half *)dataptr[0]);
    npy_float accum = half_sum_of_arr(data1, count);
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_float value1 = npy_half_to_float(*(npy_half *)dataptr[1]);
    npy_float accum = half_sum_of_arr(data0, count);
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
half_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data2 = (npy_half *)dataptr[2];
    npy_half *data_out = (npy_half *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) *
                             npy_half_to_float(data1[0]) *
                             npy_half_to_float(data2[0]) +
                             npy_half_to_float(data_out[0]));

#line 576
        data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) *
                             npy_half_to_float(data1[1]) *
                             npy_half_to_float(data2[1]) +
                             npy_half_to_float(data_out[1]));

#line 576
        data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) *
                             npy_half_to_float(data1[2]) *
                             npy_half_to_float(data2[2]) +
                             npy_half_to_float(data_out[2]));

#line 576
        data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) *
                             npy_half_to_float(data1[3]) *
                             npy_half_to_float(data2[3]) +
                             npy_half_to_float(data_out[3]));

#line 576
        data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) *
                             npy_half_to_float(data1[4]) *
                             npy_half_to_float(data2[4]) +
                             npy_half_to_float(data_out[4]));

#line 576
        data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) *
                             npy_half_to_float(data1[5]) *
                             npy_half_to_float(data2[5]) +
                             npy_half_to_float(data_out[5]));

#line 576
        data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) *
                             npy_half_to_float(data1[6]) *
                             npy_half_to_float(data2[6]) +
                             npy_half_to_float(data_out[6]));

#line 576
        data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) *
                             npy_half_to_float(data1[7]) *
                             npy_half_to_float(data2[7]) +
                             npy_half_to_float(data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) *
                         npy_half_to_float(data1[0]) *
                         npy_half_to_float(data2[0]) +
                         npy_half_to_float(data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) *
                         npy_half_to_float(data1[1]) *
                         npy_half_to_float(data2[1]) +
                         npy_half_to_float(data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) *
                         npy_half_to_float(data1[2]) *
                         npy_half_to_float(data2[2]) +
                         npy_half_to_float(data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) *
                         npy_half_to_float(data1[3]) *
                         npy_half_to_float(data2[3]) +
                         npy_half_to_float(data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) *
                         npy_half_to_float(data1[4]) *
                         npy_half_to_float(data2[4]) +
                         npy_half_to_float(data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) *
                         npy_half_to_float(data1[5]) *
                         npy_half_to_float(data2[5]) +
                         npy_half_to_float(data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) *
                         npy_half_to_float(data1[6]) *
                         npy_half_to_float(data2[6]) +
                         npy_half_to_float(data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) *
                         npy_half_to_float(data1[7]) *
                         npy_half_to_float(data2[7]) +
                         npy_half_to_float(data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
half_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        *(npy_half *)dataptr[nop] = npy_float_to_half(temp +
                                           npy_half_to_float(*(npy_half *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_half);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_half);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_half *data = (npy_half *)dataptr[0];
    npy_float accum = half_sum_of_arr(data, count);
    *((npy_half *)dataptr[1]) = npy_float_to_half(accum + npy_half_to_float(*((npy_half *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
half_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += npy_half_to_float(*(npy_half *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += npy_half_to_float(*(npy_half *)data0) *
                 npy_half_to_float(*(npy_half *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += npy_half_to_float(*(npy_half *)data0) *
                 npy_half_to_float(*(npy_half *)data1) *
                 npy_half_to_float(*(npy_half *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_float *)dataptr[2])[0] += accum_re;
    ((npy_float *)dataptr[2])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_half *)dataptr[2]) = npy_float_to_half(accum +
                                    npy_half_to_float(*((npy_half *)dataptr[2])));
#  else
    *((npy_half *)dataptr[nop]) = npy_float_to_half(accum +
                                    npy_half_to_float(*((npy_half *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
half_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) *
                                         npy_half_to_float(*(npy_half *)data1) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) *
                                         npy_half_to_float(*(npy_half *)data1) *
                                         npy_half_to_float(*(npy_half *)data2) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        *(npy_half *)dataptr[nop] = npy_float_to_half(temp +
                                           npy_half_to_float(*(npy_half *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
half_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data_out = (npy_half *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) +
                                 npy_half_to_float(data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) +
                                 npy_half_to_float(data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) +
                                 npy_half_to_float(data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) +
                                 npy_half_to_float(data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) +
                                 npy_half_to_float(data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) +
                                 npy_half_to_float(data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) +
                                 npy_half_to_float(data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) +
                             npy_half_to_float(data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) +
                             npy_half_to_float(data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) +
                             npy_half_to_float(data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) +
                             npy_half_to_float(data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) +
                             npy_half_to_float(data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) +
                             npy_half_to_float(data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) +
                             npy_half_to_float(data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) +
                             npy_half_to_float(data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
half_sum_of_products_muladd(npy_half *data, npy_half *data_out, npy_float scalar, npy_intp count)
{
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_half;
    const npyv_half v_scalar = npyv_setall_half(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_half b0 = npyv_loada_half(data + vstep * 0);
            npyv_half c0 = npyv_loada_half(data_out + vstep * 0);
            
#line 312
            npyv_half b1 = npyv_loada_half(data + vstep * 1);
            npyv_half c1 = npyv_loada_half(data_out + vstep * 1);
            
#line 312
            npyv_half b2 = npyv_loada_half(data + vstep * 2);
            npyv_half c2 = npyv_loada_half(data_out + vstep * 2);
            
#line 312
            npyv_half b3 = npyv_loada_half(data + vstep * 3);
            npyv_half c3 = npyv_loada_half(data_out + vstep * 3);
            
            #line 318
            npyv_half abc0 = npyv_muladd_half(v_scalar, b0, c0);
            
#line 318
            npyv_half abc1 = npyv_muladd_half(v_scalar, b1, c1);
            
#line 318
            npyv_half abc2 = npyv_muladd_half(v_scalar, b2, c2);
            
#line 318
            npyv_half abc3 = npyv_muladd_half(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_half(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_half(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_half(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_half(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_half b0 = npyv_load_half(data + vstep * 0);
            npyv_half c0 = npyv_load_half(data_out + vstep * 0);
            
#line 312
            npyv_half b1 = npyv_load_half(data + vstep * 1);
            npyv_half c1 = npyv_load_half(data_out + vstep * 1);
            
#line 312
            npyv_half b2 = npyv_load_half(data + vstep * 2);
            npyv_half c2 = npyv_load_half(data_out + vstep * 2);
            
#line 312
            npyv_half b3 = npyv_load_half(data + vstep * 3);
            npyv_half c3 = npyv_load_half(data_out + vstep * 3);
            
            #line 318
            npyv_half abc0 = npyv_muladd_half(v_scalar, b0, c0);
            
#line 318
            npyv_half abc1 = npyv_muladd_half(v_scalar, b1, c1);
            
#line 318
            npyv_half abc2 = npyv_muladd_half(v_scalar, b2, c2);
            
#line 318
            npyv_half abc3 = npyv_muladd_half(v_scalar, b3, c3);
            
            #line 323
            npyv_store_half(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_half(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_half(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_half(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_half a = npyv_load_tillz_half(data, count);
        npyv_half b = npyv_load_tillz_half(data_out, count);
        npyv_store_till_half(data_out, count, npyv_muladd_half(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = npy_half_to_float(data[0]);
        const npy_float c0 = npy_half_to_float(data_out[0]);
        
#line 340
        const npy_float b1 = npy_half_to_float(data[1]);
        const npy_float c1 = npy_half_to_float(data_out[1]);
        
#line 340
        const npy_float b2 = npy_half_to_float(data[2]);
        const npy_float c2 = npy_half_to_float(data_out[2]);
        
#line 340
        const npy_float b3 = npy_half_to_float(data[3]);
        const npy_float c3 = npy_half_to_float(data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = npy_float_to_half(abc0);
        
#line 351
        data_out[1] = npy_float_to_half(abc1);
        
#line 351
        data_out[2] = npy_float_to_half(abc2);
        
#line 351
        data_out[3] = npy_float_to_half(abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = npy_half_to_float(*data);
        const npy_float c = npy_half_to_float(*data_out);
        *data_out = npy_float_to_half(scalar * b + c);
    }
#endif // NPYV check for npy_half
}

static void
half_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data_out = (npy_half *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_half
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_half;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_half a0 = npyv_loada_half(data0 + vstep * 0);
            npyv_half b0 = npyv_loada_half(data1 + vstep * 0);
            npyv_half c0 = npyv_loada_half(data_out + vstep * 0);
            
#line 390
            npyv_half a1 = npyv_loada_half(data0 + vstep * 1);
            npyv_half b1 = npyv_loada_half(data1 + vstep * 1);
            npyv_half c1 = npyv_loada_half(data_out + vstep * 1);
            
#line 390
            npyv_half a2 = npyv_loada_half(data0 + vstep * 2);
            npyv_half b2 = npyv_loada_half(data1 + vstep * 2);
            npyv_half c2 = npyv_loada_half(data_out + vstep * 2);
            
#line 390
            npyv_half a3 = npyv_loada_half(data0 + vstep * 3);
            npyv_half b3 = npyv_loada_half(data1 + vstep * 3);
            npyv_half c3 = npyv_loada_half(data_out + vstep * 3);
            
            #line 397
            npyv_half abc0 = npyv_muladd_half(a0, b0, c0);
            
#line 397
            npyv_half abc1 = npyv_muladd_half(a1, b1, c1);
            
#line 397
            npyv_half abc2 = npyv_muladd_half(a2, b2, c2);
            
#line 397
            npyv_half abc3 = npyv_muladd_half(a3, b3, c3);
            
            #line 402
            npyv_storea_half(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_half(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_half(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_half(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_half a0 = npyv_load_half(data0 + vstep * 0);
            npyv_half b0 = npyv_load_half(data1 + vstep * 0);
            npyv_half c0 = npyv_load_half(data_out + vstep * 0);
            
#line 390
            npyv_half a1 = npyv_load_half(data0 + vstep * 1);
            npyv_half b1 = npyv_load_half(data1 + vstep * 1);
            npyv_half c1 = npyv_load_half(data_out + vstep * 1);
            
#line 390
            npyv_half a2 = npyv_load_half(data0 + vstep * 2);
            npyv_half b2 = npyv_load_half(data1 + vstep * 2);
            npyv_half c2 = npyv_load_half(data_out + vstep * 2);
            
#line 390
            npyv_half a3 = npyv_load_half(data0 + vstep * 3);
            npyv_half b3 = npyv_load_half(data1 + vstep * 3);
            npyv_half c3 = npyv_load_half(data_out + vstep * 3);
            
            #line 397
            npyv_half abc0 = npyv_muladd_half(a0, b0, c0);
            
#line 397
            npyv_half abc1 = npyv_muladd_half(a1, b1, c1);
            
#line 397
            npyv_half abc2 = npyv_muladd_half(a2, b2, c2);
            
#line 397
            npyv_half abc3 = npyv_muladd_half(a3, b3, c3);
            
            #line 402
            npyv_store_half(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_half(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_half(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_half(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_half a = npyv_load_tillz_half(data0, count);
        npyv_half b = npyv_load_tillz_half(data1, count);
        npyv_half c = npyv_load_tillz_half(data_out, count);
        npyv_store_till_half(data_out, count, npyv_muladd_half(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = npy_half_to_float(data0[0]);
        const npy_float b0 = npy_half_to_float(data1[0]);
        const npy_float c0 = npy_half_to_float(data_out[0]);
        
#line 420
        const npy_float a1 = npy_half_to_float(data0[1]);
        const npy_float b1 = npy_half_to_float(data1[1]);
        const npy_float c1 = npy_half_to_float(data_out[1]);
        
#line 420
        const npy_float a2 = npy_half_to_float(data0[2]);
        const npy_float b2 = npy_half_to_float(data1[2]);
        const npy_float c2 = npy_half_to_float(data_out[2]);
        
#line 420
        const npy_float a3 = npy_half_to_float(data0[3]);
        const npy_float b3 = npy_half_to_float(data1[3]);
        const npy_float c3 = npy_half_to_float(data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = npy_float_to_half(abc0);
        
#line 432
        data_out[1] = npy_float_to_half(abc1);
        
#line 432
        data_out[2] = npy_float_to_half(abc2);
        
#line 432
        data_out[3] = npy_float_to_half(abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = npy_half_to_float(*data0);
        const npy_float b = npy_half_to_float(*data1);
        const npy_float c = npy_half_to_float(*data_out);
        *data_out = npy_float_to_half(a * b + c);
    }
#endif // NPYV check for npy_half

}

/* Some extra specializations for the two operand case */
static void
half_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = npy_half_to_float(*(npy_half *)dataptr[0]);
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data_out = (npy_half *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    half_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
half_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = npy_half_to_float(*(npy_half *)dataptr[1]);
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data_out = (npy_half *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    half_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_half;
    npyv_half v_accum = npyv_zero_half();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_half a0 = npyv_loada_half(data0 + vstep * 0);
            npyv_half b0 = npyv_loada_half(data1 + vstep * 0);
            
#line 501
            npyv_half a1 = npyv_loada_half(data0 + vstep * 1);
            npyv_half b1 = npyv_loada_half(data1 + vstep * 1);
            
#line 501
            npyv_half a2 = npyv_loada_half(data0 + vstep * 2);
            npyv_half b2 = npyv_loada_half(data1 + vstep * 2);
            
#line 501
            npyv_half a3 = npyv_loada_half(data0 + vstep * 3);
            npyv_half b3 = npyv_loada_half(data1 + vstep * 3);
            
            npyv_half ab3 = npyv_muladd_half(a3, b3, v_accum);
            npyv_half ab2 = npyv_muladd_half(a2, b2, ab3);
            npyv_half ab1 = npyv_muladd_half(a1, b1, ab2);
                   v_accum = npyv_muladd_half(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_half a0 = npyv_load_half(data0 + vstep * 0);
            npyv_half b0 = npyv_load_half(data1 + vstep * 0);
            
#line 501
            npyv_half a1 = npyv_load_half(data0 + vstep * 1);
            npyv_half b1 = npyv_load_half(data1 + vstep * 1);
            
#line 501
            npyv_half a2 = npyv_load_half(data0 + vstep * 2);
            npyv_half b2 = npyv_load_half(data1 + vstep * 2);
            
#line 501
            npyv_half a3 = npyv_load_half(data0 + vstep * 3);
            npyv_half b3 = npyv_load_half(data1 + vstep * 3);
            
            npyv_half ab3 = npyv_muladd_half(a3, b3, v_accum);
            npyv_half ab2 = npyv_muladd_half(a2, b2, ab3);
            npyv_half ab1 = npyv_muladd_half(a1, b1, ab2);
                   v_accum = npyv_muladd_half(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_half a = npyv_load_tillz_half(data0, count);
        npyv_half b = npyv_load_tillz_half(data1, count);
        v_accum = npyv_muladd_half(a, b, v_accum);
    }
    accum = npyv_sum_half(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = npy_half_to_float(data0[0]) * npy_half_to_float(data1[0]);
        
#line 524
        const npy_float ab1 = npy_half_to_float(data0[1]) * npy_half_to_float(data1[1]);
        
#line 524
        const npy_float ab2 = npy_half_to_float(data0[2]) * npy_half_to_float(data1[2]);
        
#line 524
        const npy_float ab3 = npy_half_to_float(data0[3]) * npy_half_to_float(data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = npy_half_to_float(*data0);
        const npy_float b = npy_half_to_float(*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_half
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_float value0 = npy_half_to_float(*(npy_half *)dataptr[0]);
    npy_float accum = half_sum_of_arr(data1, count);
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_float value1 = npy_half_to_float(*(npy_half *)dataptr[1]);
    npy_float accum = half_sum_of_arr(data0, count);
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
half_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data2 = (npy_half *)dataptr[2];
    npy_half *data_out = (npy_half *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) *
                             npy_half_to_float(data1[0]) *
                             npy_half_to_float(data2[0]) +
                             npy_half_to_float(data_out[0]));

#line 576
        data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) *
                             npy_half_to_float(data1[1]) *
                             npy_half_to_float(data2[1]) +
                             npy_half_to_float(data_out[1]));

#line 576
        data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) *
                             npy_half_to_float(data1[2]) *
                             npy_half_to_float(data2[2]) +
                             npy_half_to_float(data_out[2]));

#line 576
        data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) *
                             npy_half_to_float(data1[3]) *
                             npy_half_to_float(data2[3]) +
                             npy_half_to_float(data_out[3]));

#line 576
        data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) *
                             npy_half_to_float(data1[4]) *
                             npy_half_to_float(data2[4]) +
                             npy_half_to_float(data_out[4]));

#line 576
        data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) *
                             npy_half_to_float(data1[5]) *
                             npy_half_to_float(data2[5]) +
                             npy_half_to_float(data_out[5]));

#line 576
        data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) *
                             npy_half_to_float(data1[6]) *
                             npy_half_to_float(data2[6]) +
                             npy_half_to_float(data_out[6]));

#line 576
        data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) *
                             npy_half_to_float(data1[7]) *
                             npy_half_to_float(data2[7]) +
                             npy_half_to_float(data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) *
                         npy_half_to_float(data1[0]) *
                         npy_half_to_float(data2[0]) +
                         npy_half_to_float(data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) *
                         npy_half_to_float(data1[1]) *
                         npy_half_to_float(data2[1]) +
                         npy_half_to_float(data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) *
                         npy_half_to_float(data1[2]) *
                         npy_half_to_float(data2[2]) +
                         npy_half_to_float(data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) *
                         npy_half_to_float(data1[3]) *
                         npy_half_to_float(data2[3]) +
                         npy_half_to_float(data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) *
                         npy_half_to_float(data1[4]) *
                         npy_half_to_float(data2[4]) +
                         npy_half_to_float(data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) *
                         npy_half_to_float(data1[5]) *
                         npy_half_to_float(data2[5]) +
                         npy_half_to_float(data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) *
                         npy_half_to_float(data1[6]) *
                         npy_half_to_float(data2[6]) +
                         npy_half_to_float(data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) *
                         npy_half_to_float(data1[7]) *
                         npy_half_to_float(data2[7]) +
                         npy_half_to_float(data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
half_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        *(npy_half *)dataptr[nop] = npy_float_to_half(temp +
                                           npy_half_to_float(*(npy_half *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_half);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_half);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_half *data = (npy_half *)dataptr[0];
    npy_float accum = half_sum_of_arr(data, count);
    *((npy_half *)dataptr[1]) = npy_float_to_half(accum + npy_half_to_float(*((npy_half *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
half_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += npy_half_to_float(*(npy_half *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += npy_half_to_float(*(npy_half *)data0) *
                 npy_half_to_float(*(npy_half *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += npy_half_to_float(*(npy_half *)data0) *
                 npy_half_to_float(*(npy_half *)data1) *
                 npy_half_to_float(*(npy_half *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_float *)dataptr[3])[0] += accum_re;
    ((npy_float *)dataptr[3])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_half *)dataptr[3]) = npy_float_to_half(accum +
                                    npy_half_to_float(*((npy_half *)dataptr[3])));
#  else
    *((npy_half *)dataptr[nop]) = npy_float_to_half(accum +
                                    npy_half_to_float(*((npy_half *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
half_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) *
                                         npy_half_to_float(*(npy_half *)data1) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_half *)data_out = npy_float_to_half(npy_half_to_float(*(npy_half *)data0) *
                                         npy_half_to_float(*(npy_half *)data1) *
                                         npy_half_to_float(*(npy_half *)data2) +
                                         npy_half_to_float(*(npy_half *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        *(npy_half *)dataptr[nop] = npy_float_to_half(temp +
                                           npy_half_to_float(*(npy_half *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
half_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data_out = (npy_half *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) +
                                 npy_half_to_float(data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) +
                                 npy_half_to_float(data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) +
                                 npy_half_to_float(data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) +
                                 npy_half_to_float(data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) +
                                 npy_half_to_float(data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) +
                                 npy_half_to_float(data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) +
                                 npy_half_to_float(data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) +
                             npy_half_to_float(data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) +
                             npy_half_to_float(data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) +
                             npy_half_to_float(data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) +
                             npy_half_to_float(data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) +
                             npy_half_to_float(data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) +
                             npy_half_to_float(data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) +
                             npy_half_to_float(data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) +
                             npy_half_to_float(data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
half_sum_of_products_muladd(npy_half *data, npy_half *data_out, npy_float scalar, npy_intp count)
{
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_half;
    const npyv_half v_scalar = npyv_setall_half(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_half b0 = npyv_loada_half(data + vstep * 0);
            npyv_half c0 = npyv_loada_half(data_out + vstep * 0);
            
#line 312
            npyv_half b1 = npyv_loada_half(data + vstep * 1);
            npyv_half c1 = npyv_loada_half(data_out + vstep * 1);
            
#line 312
            npyv_half b2 = npyv_loada_half(data + vstep * 2);
            npyv_half c2 = npyv_loada_half(data_out + vstep * 2);
            
#line 312
            npyv_half b3 = npyv_loada_half(data + vstep * 3);
            npyv_half c3 = npyv_loada_half(data_out + vstep * 3);
            
            #line 318
            npyv_half abc0 = npyv_muladd_half(v_scalar, b0, c0);
            
#line 318
            npyv_half abc1 = npyv_muladd_half(v_scalar, b1, c1);
            
#line 318
            npyv_half abc2 = npyv_muladd_half(v_scalar, b2, c2);
            
#line 318
            npyv_half abc3 = npyv_muladd_half(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_half(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_half(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_half(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_half(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_half b0 = npyv_load_half(data + vstep * 0);
            npyv_half c0 = npyv_load_half(data_out + vstep * 0);
            
#line 312
            npyv_half b1 = npyv_load_half(data + vstep * 1);
            npyv_half c1 = npyv_load_half(data_out + vstep * 1);
            
#line 312
            npyv_half b2 = npyv_load_half(data + vstep * 2);
            npyv_half c2 = npyv_load_half(data_out + vstep * 2);
            
#line 312
            npyv_half b3 = npyv_load_half(data + vstep * 3);
            npyv_half c3 = npyv_load_half(data_out + vstep * 3);
            
            #line 318
            npyv_half abc0 = npyv_muladd_half(v_scalar, b0, c0);
            
#line 318
            npyv_half abc1 = npyv_muladd_half(v_scalar, b1, c1);
            
#line 318
            npyv_half abc2 = npyv_muladd_half(v_scalar, b2, c2);
            
#line 318
            npyv_half abc3 = npyv_muladd_half(v_scalar, b3, c3);
            
            #line 323
            npyv_store_half(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_half(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_half(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_half(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_half a = npyv_load_tillz_half(data, count);
        npyv_half b = npyv_load_tillz_half(data_out, count);
        npyv_store_till_half(data_out, count, npyv_muladd_half(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = npy_half_to_float(data[0]);
        const npy_float c0 = npy_half_to_float(data_out[0]);
        
#line 340
        const npy_float b1 = npy_half_to_float(data[1]);
        const npy_float c1 = npy_half_to_float(data_out[1]);
        
#line 340
        const npy_float b2 = npy_half_to_float(data[2]);
        const npy_float c2 = npy_half_to_float(data_out[2]);
        
#line 340
        const npy_float b3 = npy_half_to_float(data[3]);
        const npy_float c3 = npy_half_to_float(data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = npy_float_to_half(abc0);
        
#line 351
        data_out[1] = npy_float_to_half(abc1);
        
#line 351
        data_out[2] = npy_float_to_half(abc2);
        
#line 351
        data_out[3] = npy_float_to_half(abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = npy_half_to_float(*data);
        const npy_float c = npy_half_to_float(*data_out);
        *data_out = npy_float_to_half(scalar * b + c);
    }
#endif // NPYV check for npy_half
}

static void
half_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data_out = (npy_half *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_half
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_half;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_half a0 = npyv_loada_half(data0 + vstep * 0);
            npyv_half b0 = npyv_loada_half(data1 + vstep * 0);
            npyv_half c0 = npyv_loada_half(data_out + vstep * 0);
            
#line 390
            npyv_half a1 = npyv_loada_half(data0 + vstep * 1);
            npyv_half b1 = npyv_loada_half(data1 + vstep * 1);
            npyv_half c1 = npyv_loada_half(data_out + vstep * 1);
            
#line 390
            npyv_half a2 = npyv_loada_half(data0 + vstep * 2);
            npyv_half b2 = npyv_loada_half(data1 + vstep * 2);
            npyv_half c2 = npyv_loada_half(data_out + vstep * 2);
            
#line 390
            npyv_half a3 = npyv_loada_half(data0 + vstep * 3);
            npyv_half b3 = npyv_loada_half(data1 + vstep * 3);
            npyv_half c3 = npyv_loada_half(data_out + vstep * 3);
            
            #line 397
            npyv_half abc0 = npyv_muladd_half(a0, b0, c0);
            
#line 397
            npyv_half abc1 = npyv_muladd_half(a1, b1, c1);
            
#line 397
            npyv_half abc2 = npyv_muladd_half(a2, b2, c2);
            
#line 397
            npyv_half abc3 = npyv_muladd_half(a3, b3, c3);
            
            #line 402
            npyv_storea_half(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_half(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_half(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_half(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_half a0 = npyv_load_half(data0 + vstep * 0);
            npyv_half b0 = npyv_load_half(data1 + vstep * 0);
            npyv_half c0 = npyv_load_half(data_out + vstep * 0);
            
#line 390
            npyv_half a1 = npyv_load_half(data0 + vstep * 1);
            npyv_half b1 = npyv_load_half(data1 + vstep * 1);
            npyv_half c1 = npyv_load_half(data_out + vstep * 1);
            
#line 390
            npyv_half a2 = npyv_load_half(data0 + vstep * 2);
            npyv_half b2 = npyv_load_half(data1 + vstep * 2);
            npyv_half c2 = npyv_load_half(data_out + vstep * 2);
            
#line 390
            npyv_half a3 = npyv_load_half(data0 + vstep * 3);
            npyv_half b3 = npyv_load_half(data1 + vstep * 3);
            npyv_half c3 = npyv_load_half(data_out + vstep * 3);
            
            #line 397
            npyv_half abc0 = npyv_muladd_half(a0, b0, c0);
            
#line 397
            npyv_half abc1 = npyv_muladd_half(a1, b1, c1);
            
#line 397
            npyv_half abc2 = npyv_muladd_half(a2, b2, c2);
            
#line 397
            npyv_half abc3 = npyv_muladd_half(a3, b3, c3);
            
            #line 402
            npyv_store_half(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_half(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_half(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_half(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_half a = npyv_load_tillz_half(data0, count);
        npyv_half b = npyv_load_tillz_half(data1, count);
        npyv_half c = npyv_load_tillz_half(data_out, count);
        npyv_store_till_half(data_out, count, npyv_muladd_half(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = npy_half_to_float(data0[0]);
        const npy_float b0 = npy_half_to_float(data1[0]);
        const npy_float c0 = npy_half_to_float(data_out[0]);
        
#line 420
        const npy_float a1 = npy_half_to_float(data0[1]);
        const npy_float b1 = npy_half_to_float(data1[1]);
        const npy_float c1 = npy_half_to_float(data_out[1]);
        
#line 420
        const npy_float a2 = npy_half_to_float(data0[2]);
        const npy_float b2 = npy_half_to_float(data1[2]);
        const npy_float c2 = npy_half_to_float(data_out[2]);
        
#line 420
        const npy_float a3 = npy_half_to_float(data0[3]);
        const npy_float b3 = npy_half_to_float(data1[3]);
        const npy_float c3 = npy_half_to_float(data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = npy_float_to_half(abc0);
        
#line 432
        data_out[1] = npy_float_to_half(abc1);
        
#line 432
        data_out[2] = npy_float_to_half(abc2);
        
#line 432
        data_out[3] = npy_float_to_half(abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = npy_half_to_float(*data0);
        const npy_float b = npy_half_to_float(*data1);
        const npy_float c = npy_half_to_float(*data_out);
        *data_out = npy_float_to_half(a * b + c);
    }
#endif // NPYV check for npy_half

}

/* Some extra specializations for the two operand case */
static void
half_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = npy_half_to_float(*(npy_half *)dataptr[0]);
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data_out = (npy_half *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    half_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
half_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = npy_half_to_float(*(npy_half *)dataptr[1]);
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data_out = (npy_half *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    half_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_half
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_half;
    npyv_half v_accum = npyv_zero_half();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_half a0 = npyv_loada_half(data0 + vstep * 0);
            npyv_half b0 = npyv_loada_half(data1 + vstep * 0);
            
#line 501
            npyv_half a1 = npyv_loada_half(data0 + vstep * 1);
            npyv_half b1 = npyv_loada_half(data1 + vstep * 1);
            
#line 501
            npyv_half a2 = npyv_loada_half(data0 + vstep * 2);
            npyv_half b2 = npyv_loada_half(data1 + vstep * 2);
            
#line 501
            npyv_half a3 = npyv_loada_half(data0 + vstep * 3);
            npyv_half b3 = npyv_loada_half(data1 + vstep * 3);
            
            npyv_half ab3 = npyv_muladd_half(a3, b3, v_accum);
            npyv_half ab2 = npyv_muladd_half(a2, b2, ab3);
            npyv_half ab1 = npyv_muladd_half(a1, b1, ab2);
                   v_accum = npyv_muladd_half(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_half a0 = npyv_load_half(data0 + vstep * 0);
            npyv_half b0 = npyv_load_half(data1 + vstep * 0);
            
#line 501
            npyv_half a1 = npyv_load_half(data0 + vstep * 1);
            npyv_half b1 = npyv_load_half(data1 + vstep * 1);
            
#line 501
            npyv_half a2 = npyv_load_half(data0 + vstep * 2);
            npyv_half b2 = npyv_load_half(data1 + vstep * 2);
            
#line 501
            npyv_half a3 = npyv_load_half(data0 + vstep * 3);
            npyv_half b3 = npyv_load_half(data1 + vstep * 3);
            
            npyv_half ab3 = npyv_muladd_half(a3, b3, v_accum);
            npyv_half ab2 = npyv_muladd_half(a2, b2, ab3);
            npyv_half ab1 = npyv_muladd_half(a1, b1, ab2);
                   v_accum = npyv_muladd_half(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_half a = npyv_load_tillz_half(data0, count);
        npyv_half b = npyv_load_tillz_half(data1, count);
        v_accum = npyv_muladd_half(a, b, v_accum);
    }
    accum = npyv_sum_half(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = npy_half_to_float(data0[0]) * npy_half_to_float(data1[0]);
        
#line 524
        const npy_float ab1 = npy_half_to_float(data0[1]) * npy_half_to_float(data1[1]);
        
#line 524
        const npy_float ab2 = npy_half_to_float(data0[2]) * npy_half_to_float(data1[2]);
        
#line 524
        const npy_float ab3 = npy_half_to_float(data0[3]) * npy_half_to_float(data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = npy_half_to_float(*data0);
        const npy_float b = npy_half_to_float(*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_half
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_float value0 = npy_half_to_float(*(npy_half *)dataptr[0]);
    npy_float accum = half_sum_of_arr(data1, count);
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_float value1 = npy_half_to_float(*(npy_half *)dataptr[1]);
    npy_float accum = half_sum_of_arr(data0, count);
    *(npy_half *)dataptr[2] = npy_float_to_half(npy_half_to_float(*(npy_half *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
half_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_half *data0 = (npy_half *)dataptr[0];
    npy_half *data1 = (npy_half *)dataptr[1];
    npy_half *data2 = (npy_half *)dataptr[2];
    npy_half *data_out = (npy_half *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) *
                             npy_half_to_float(data1[0]) *
                             npy_half_to_float(data2[0]) +
                             npy_half_to_float(data_out[0]));

#line 576
        data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) *
                             npy_half_to_float(data1[1]) *
                             npy_half_to_float(data2[1]) +
                             npy_half_to_float(data_out[1]));

#line 576
        data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) *
                             npy_half_to_float(data1[2]) *
                             npy_half_to_float(data2[2]) +
                             npy_half_to_float(data_out[2]));

#line 576
        data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) *
                             npy_half_to_float(data1[3]) *
                             npy_half_to_float(data2[3]) +
                             npy_half_to_float(data_out[3]));

#line 576
        data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) *
                             npy_half_to_float(data1[4]) *
                             npy_half_to_float(data2[4]) +
                             npy_half_to_float(data_out[4]));

#line 576
        data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) *
                             npy_half_to_float(data1[5]) *
                             npy_half_to_float(data2[5]) +
                             npy_half_to_float(data_out[5]));

#line 576
        data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) *
                             npy_half_to_float(data1[6]) *
                             npy_half_to_float(data2[6]) +
                             npy_half_to_float(data_out[6]));

#line 576
        data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) *
                             npy_half_to_float(data1[7]) *
                             npy_half_to_float(data2[7]) +
                             npy_half_to_float(data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = npy_float_to_half(npy_half_to_float(data0[0]) *
                         npy_half_to_float(data1[0]) *
                         npy_half_to_float(data2[0]) +
                         npy_half_to_float(data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = npy_float_to_half(npy_half_to_float(data0[1]) *
                         npy_half_to_float(data1[1]) *
                         npy_half_to_float(data2[1]) +
                         npy_half_to_float(data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = npy_float_to_half(npy_half_to_float(data0[2]) *
                         npy_half_to_float(data1[2]) *
                         npy_half_to_float(data2[2]) +
                         npy_half_to_float(data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = npy_float_to_half(npy_half_to_float(data0[3]) *
                         npy_half_to_float(data1[3]) *
                         npy_half_to_float(data2[3]) +
                         npy_half_to_float(data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = npy_float_to_half(npy_half_to_float(data0[4]) *
                         npy_half_to_float(data1[4]) *
                         npy_half_to_float(data2[4]) +
                         npy_half_to_float(data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = npy_float_to_half(npy_half_to_float(data0[5]) *
                         npy_half_to_float(data1[5]) *
                         npy_half_to_float(data2[5]) +
                         npy_half_to_float(data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = npy_float_to_half(npy_half_to_float(data0[6]) *
                         npy_half_to_float(data1[6]) *
                         npy_half_to_float(data2[6]) +
                         npy_half_to_float(data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = npy_float_to_half(npy_half_to_float(data0[7]) *
                         npy_half_to_float(data1[7]) *
                         npy_half_to_float(data2[7]) +
                         npy_half_to_float(data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
half_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        *(npy_half *)dataptr[nop] = npy_float_to_half(temp +
                                           npy_half_to_float(*(npy_half *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_half);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_half);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
half_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_half *data = (npy_half *)dataptr[0];
    npy_float accum = half_sum_of_arr(data, count);
    *((npy_half *)dataptr[1]) = npy_float_to_half(accum + npy_half_to_float(*((npy_half *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
half_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("half_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += npy_half_to_float(*(npy_half *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += npy_half_to_float(*(npy_half *)data0) *
                 npy_half_to_float(*(npy_half *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += npy_half_to_float(*(npy_half *)data0) *
                 npy_half_to_float(*(npy_half *)data1) *
                 npy_half_to_float(*(npy_half *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = npy_half_to_float(*(npy_half *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= npy_half_to_float(*(npy_half *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_float *)dataptr[1000])[0] += accum_re;
    ((npy_float *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_half *)dataptr[1000]) = npy_float_to_half(accum +
                                    npy_half_to_float(*((npy_half *)dataptr[1000])));
#  else
    *((npy_half *)dataptr[nop]) = npy_float_to_half(accum +
                                    npy_half_to_float(*((npy_half *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_float float_sum_of_arr(npy_float *data, npy_intp count)
{
    npy_float accum = 0;
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_f32 a0 = npyv_loada_f32(data + vstep * 0);
            
#line 96
            npyv_f32 a1 = npyv_loada_f32(data + vstep * 1);
            
#line 96
            npyv_f32 a2 = npyv_loada_f32(data + vstep * 2);
            
#line 96
            npyv_f32 a3 = npyv_loada_f32(data + vstep * 3);
            
            npyv_f32 a01   = npyv_add_f32(a0, a1);
            npyv_f32 a23   = npyv_add_f32(a2, a3);
            npyv_f32 a0123 = npyv_add_f32(a01, a23);
                     v_accum = npyv_add_f32(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_f32 a0 = npyv_load_f32(data + vstep * 0);
            
#line 96
            npyv_f32 a1 = npyv_load_f32(data + vstep * 1);
            
#line 96
            npyv_f32 a2 = npyv_load_f32(data + vstep * 2);
            
#line 96
            npyv_f32 a3 = npyv_load_f32(data + vstep * 3);
            
            npyv_f32 a01   = npyv_add_f32(a0, a1);
            npyv_f32 a23   = npyv_add_f32(a2, a3);
            npyv_f32 a0123 = npyv_add_f32(a01, a23);
                     v_accum = npyv_add_f32(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        v_accum = npyv_add_f32(a, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_float a01 = (*data) + (data[1]);
        const npy_float a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_float
    return accum;
}
#endif

#line 131
static void
float_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_float *)data_out = ((*(npy_float *)data0) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_float *)data_out = ((*(npy_float *)data0) *
                                         (*(npy_float *)data1) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_float *)data_out = ((*(npy_float *)data0) *
                                         (*(npy_float *)data1) *
                                         (*(npy_float *)data2) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        *(npy_float *)dataptr[nop] = (temp +
                                           (*(npy_float *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
float_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data_out = (npy_float *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
float_sum_of_products_muladd(npy_float *data, npy_float *data_out, npy_float scalar, npy_intp count)
{
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;
    const npyv_f32 v_scalar = npyv_setall_f32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_loada_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_loada_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_loada_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_loada_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_load_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_load_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_load_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_load_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        npyv_f32 b = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = (data[0]);
        const npy_float c0 = (data_out[0]);
        
#line 340
        const npy_float b1 = (data[1]);
        const npy_float c1 = (data_out[1]);
        
#line 340
        const npy_float b2 = (data[2]);
        const npy_float c2 = (data_out[2]);
        
#line 340
        const npy_float b3 = (data[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = (*data);
        const npy_float c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_float
}

static void
float_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data_out = (npy_float *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_float
#if NPY_SIMD_F32
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        npyv_f32 c = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = (data0[0]);
        const npy_float b0 = (data1[0]);
        const npy_float c0 = (data_out[0]);
        
#line 420
        const npy_float a1 = (data0[1]);
        const npy_float b1 = (data1[1]);
        const npy_float c1 = (data_out[1]);
        
#line 420
        const npy_float a2 = (data0[2]);
        const npy_float b2 = (data1[2]);
        const npy_float c2 = (data_out[2]);
        
#line 420
        const npy_float a3 = (data0[3]);
        const npy_float b3 = (data1[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        const npy_float c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_float

}

/* Some extra specializations for the two operand case */
static void
float_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = (*(npy_float *)dataptr[0]);
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data_out = (npy_float *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    float_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
float_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = (*(npy_float *)dataptr[1]);
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data_out = (npy_float *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    float_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        v_accum = npyv_muladd_f32(a, b, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_float ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_float ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_float ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_float
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float value0 = (*(npy_float *)dataptr[0]);
    npy_float accum = float_sum_of_arr(data1, count);
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float value1 = (*(npy_float *)dataptr[1]);
    npy_float accum = float_sum_of_arr(data0, count);
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
float_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data2 = (npy_float *)dataptr[2];
    npy_float *data_out = (npy_float *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
float_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        *(npy_float *)dataptr[nop] = (temp +
                                           (*(npy_float *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_float);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_float);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_float *data = (npy_float *)dataptr[0];
    npy_float accum = float_sum_of_arr(data, count);
    *((npy_float *)dataptr[1]) = (accum + (*((npy_float *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
float_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_float *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_float *)data0) *
                 (*(npy_float *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_float *)data0) *
                 (*(npy_float *)data1) *
                 (*(npy_float *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_float *)dataptr[1]) = (accum +
                                    (*((npy_float *)dataptr[1])));
#  else
    *((npy_float *)dataptr[nop]) = (accum +
                                    (*((npy_float *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
float_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_float *)data_out = ((*(npy_float *)data0) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_float *)data_out = ((*(npy_float *)data0) *
                                         (*(npy_float *)data1) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_float *)data_out = ((*(npy_float *)data0) *
                                         (*(npy_float *)data1) *
                                         (*(npy_float *)data2) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        *(npy_float *)dataptr[nop] = (temp +
                                           (*(npy_float *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
float_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data_out = (npy_float *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
float_sum_of_products_muladd(npy_float *data, npy_float *data_out, npy_float scalar, npy_intp count)
{
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;
    const npyv_f32 v_scalar = npyv_setall_f32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_loada_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_loada_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_loada_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_loada_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_load_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_load_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_load_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_load_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        npyv_f32 b = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = (data[0]);
        const npy_float c0 = (data_out[0]);
        
#line 340
        const npy_float b1 = (data[1]);
        const npy_float c1 = (data_out[1]);
        
#line 340
        const npy_float b2 = (data[2]);
        const npy_float c2 = (data_out[2]);
        
#line 340
        const npy_float b3 = (data[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = (*data);
        const npy_float c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_float
}

static void
float_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data_out = (npy_float *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_float
#if NPY_SIMD_F32
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        npyv_f32 c = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = (data0[0]);
        const npy_float b0 = (data1[0]);
        const npy_float c0 = (data_out[0]);
        
#line 420
        const npy_float a1 = (data0[1]);
        const npy_float b1 = (data1[1]);
        const npy_float c1 = (data_out[1]);
        
#line 420
        const npy_float a2 = (data0[2]);
        const npy_float b2 = (data1[2]);
        const npy_float c2 = (data_out[2]);
        
#line 420
        const npy_float a3 = (data0[3]);
        const npy_float b3 = (data1[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        const npy_float c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_float

}

/* Some extra specializations for the two operand case */
static void
float_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = (*(npy_float *)dataptr[0]);
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data_out = (npy_float *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    float_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
float_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = (*(npy_float *)dataptr[1]);
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data_out = (npy_float *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    float_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        v_accum = npyv_muladd_f32(a, b, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_float ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_float ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_float ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_float
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float value0 = (*(npy_float *)dataptr[0]);
    npy_float accum = float_sum_of_arr(data1, count);
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float value1 = (*(npy_float *)dataptr[1]);
    npy_float accum = float_sum_of_arr(data0, count);
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
float_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data2 = (npy_float *)dataptr[2];
    npy_float *data_out = (npy_float *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
float_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        *(npy_float *)dataptr[nop] = (temp +
                                           (*(npy_float *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_float);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_float);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_float *data = (npy_float *)dataptr[0];
    npy_float accum = float_sum_of_arr(data, count);
    *((npy_float *)dataptr[1]) = (accum + (*((npy_float *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
float_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_float *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_float *)data0) *
                 (*(npy_float *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_float *)data0) *
                 (*(npy_float *)data1) *
                 (*(npy_float *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_float *)dataptr[2])[0] += accum_re;
    ((npy_float *)dataptr[2])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_float *)dataptr[2]) = (accum +
                                    (*((npy_float *)dataptr[2])));
#  else
    *((npy_float *)dataptr[nop]) = (accum +
                                    (*((npy_float *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
float_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_float *)data_out = ((*(npy_float *)data0) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_float *)data_out = ((*(npy_float *)data0) *
                                         (*(npy_float *)data1) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_float *)data_out = ((*(npy_float *)data0) *
                                         (*(npy_float *)data1) *
                                         (*(npy_float *)data2) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        *(npy_float *)dataptr[nop] = (temp +
                                           (*(npy_float *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
float_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data_out = (npy_float *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
float_sum_of_products_muladd(npy_float *data, npy_float *data_out, npy_float scalar, npy_intp count)
{
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;
    const npyv_f32 v_scalar = npyv_setall_f32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_loada_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_loada_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_loada_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_loada_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_load_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_load_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_load_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_load_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        npyv_f32 b = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = (data[0]);
        const npy_float c0 = (data_out[0]);
        
#line 340
        const npy_float b1 = (data[1]);
        const npy_float c1 = (data_out[1]);
        
#line 340
        const npy_float b2 = (data[2]);
        const npy_float c2 = (data_out[2]);
        
#line 340
        const npy_float b3 = (data[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = (*data);
        const npy_float c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_float
}

static void
float_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data_out = (npy_float *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_float
#if NPY_SIMD_F32
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        npyv_f32 c = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = (data0[0]);
        const npy_float b0 = (data1[0]);
        const npy_float c0 = (data_out[0]);
        
#line 420
        const npy_float a1 = (data0[1]);
        const npy_float b1 = (data1[1]);
        const npy_float c1 = (data_out[1]);
        
#line 420
        const npy_float a2 = (data0[2]);
        const npy_float b2 = (data1[2]);
        const npy_float c2 = (data_out[2]);
        
#line 420
        const npy_float a3 = (data0[3]);
        const npy_float b3 = (data1[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        const npy_float c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_float

}

/* Some extra specializations for the two operand case */
static void
float_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = (*(npy_float *)dataptr[0]);
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data_out = (npy_float *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    float_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
float_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = (*(npy_float *)dataptr[1]);
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data_out = (npy_float *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    float_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        v_accum = npyv_muladd_f32(a, b, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_float ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_float ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_float ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_float
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float value0 = (*(npy_float *)dataptr[0]);
    npy_float accum = float_sum_of_arr(data1, count);
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float value1 = (*(npy_float *)dataptr[1]);
    npy_float accum = float_sum_of_arr(data0, count);
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
float_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data2 = (npy_float *)dataptr[2];
    npy_float *data_out = (npy_float *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
float_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        *(npy_float *)dataptr[nop] = (temp +
                                           (*(npy_float *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_float);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_float);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_float *data = (npy_float *)dataptr[0];
    npy_float accum = float_sum_of_arr(data, count);
    *((npy_float *)dataptr[1]) = (accum + (*((npy_float *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
float_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_float *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_float *)data0) *
                 (*(npy_float *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_float *)data0) *
                 (*(npy_float *)data1) *
                 (*(npy_float *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_float *)dataptr[3])[0] += accum_re;
    ((npy_float *)dataptr[3])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_float *)dataptr[3]) = (accum +
                                    (*((npy_float *)dataptr[3])));
#  else
    *((npy_float *)dataptr[nop]) = (accum +
                                    (*((npy_float *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
float_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_float *)data_out = ((*(npy_float *)data0) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_float *)data_out = ((*(npy_float *)data0) *
                                         (*(npy_float *)data1) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_float *)data_out = ((*(npy_float *)data0) *
                                         (*(npy_float *)data1) *
                                         (*(npy_float *)data2) +
                                         (*(npy_float *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        *(npy_float *)dataptr[nop] = (temp +
                                           (*(npy_float *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
float_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data_out = (npy_float *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
float_sum_of_products_muladd(npy_float *data, npy_float *data_out, npy_float scalar, npy_intp count)
{
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;
    const npyv_f32 v_scalar = npyv_setall_f32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_loada_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_loada_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_loada_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_loada_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_load_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_load_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_load_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_load_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        npyv_f32 b = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = (data[0]);
        const npy_float c0 = (data_out[0]);
        
#line 340
        const npy_float b1 = (data[1]);
        const npy_float c1 = (data_out[1]);
        
#line 340
        const npy_float b2 = (data[2]);
        const npy_float c2 = (data_out[2]);
        
#line 340
        const npy_float b3 = (data[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = (*data);
        const npy_float c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_float
}

static void
float_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data_out = (npy_float *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_float
#if NPY_SIMD_F32
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        npyv_f32 c = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = (data0[0]);
        const npy_float b0 = (data1[0]);
        const npy_float c0 = (data_out[0]);
        
#line 420
        const npy_float a1 = (data0[1]);
        const npy_float b1 = (data1[1]);
        const npy_float c1 = (data_out[1]);
        
#line 420
        const npy_float a2 = (data0[2]);
        const npy_float b2 = (data1[2]);
        const npy_float c2 = (data_out[2]);
        
#line 420
        const npy_float a3 = (data0[3]);
        const npy_float b3 = (data1[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        const npy_float c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_float

}

/* Some extra specializations for the two operand case */
static void
float_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = (*(npy_float *)dataptr[0]);
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data_out = (npy_float *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    float_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
float_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = (*(npy_float *)dataptr[1]);
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data_out = (npy_float *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    float_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if NPY_SIMD_F32 // NPYV check for npy_float
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        v_accum = npyv_muladd_f32(a, b, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_float ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_float ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_float ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_float
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float value0 = (*(npy_float *)dataptr[0]);
    npy_float accum = float_sum_of_arr(data1, count);
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float value1 = (*(npy_float *)dataptr[1]);
    npy_float accum = float_sum_of_arr(data0, count);
    *(npy_float *)dataptr[2] = ((*(npy_float *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
float_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float *data0 = (npy_float *)dataptr[0];
    npy_float *data1 = (npy_float *)dataptr[1];
    npy_float *data2 = (npy_float *)dataptr[2];
    npy_float *data_out = (npy_float *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
float_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        *(npy_float *)dataptr[nop] = (temp +
                                           (*(npy_float *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_float);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_float);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
float_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_float *data = (npy_float *)dataptr[0];
    npy_float accum = float_sum_of_arr(data, count);
    *((npy_float *)dataptr[1]) = (accum + (*((npy_float *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
float_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("float_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_float *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_float *)data0) *
                 (*(npy_float *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_float *)data0) *
                 (*(npy_float *)data1) *
                 (*(npy_float *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = (*(npy_float *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_float *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_float *)dataptr[1000])[0] += accum_re;
    ((npy_float *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_float *)dataptr[1000]) = (accum +
                                    (*((npy_float *)dataptr[1000])));
#  else
    *((npy_float *)dataptr[nop]) = (accum +
                                    (*((npy_float *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_double double_sum_of_arr(npy_double *data, npy_intp count)
{
    npy_double accum = 0;
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_f64 a0 = npyv_loada_f64(data + vstep * 0);
            
#line 96
            npyv_f64 a1 = npyv_loada_f64(data + vstep * 1);
            
#line 96
            npyv_f64 a2 = npyv_loada_f64(data + vstep * 2);
            
#line 96
            npyv_f64 a3 = npyv_loada_f64(data + vstep * 3);
            
            npyv_f64 a01   = npyv_add_f64(a0, a1);
            npyv_f64 a23   = npyv_add_f64(a2, a3);
            npyv_f64 a0123 = npyv_add_f64(a01, a23);
                     v_accum = npyv_add_f64(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_f64 a0 = npyv_load_f64(data + vstep * 0);
            
#line 96
            npyv_f64 a1 = npyv_load_f64(data + vstep * 1);
            
#line 96
            npyv_f64 a2 = npyv_load_f64(data + vstep * 2);
            
#line 96
            npyv_f64 a3 = npyv_load_f64(data + vstep * 3);
            
            npyv_f64 a01   = npyv_add_f64(a0, a1);
            npyv_f64 a23   = npyv_add_f64(a2, a3);
            npyv_f64 a0123 = npyv_add_f64(a01, a23);
                     v_accum = npyv_add_f64(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        v_accum = npyv_add_f64(a, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_double a01 = (*data) + (data[1]);
        const npy_double a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_double
    return accum;
}
#endif

#line 131
static void
double_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_double *)data_out = ((*(npy_double *)data0) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_double *)data_out = ((*(npy_double *)data0) *
                                         (*(npy_double *)data1) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_double *)data_out = ((*(npy_double *)data0) *
                                         (*(npy_double *)data1) *
                                         (*(npy_double *)data2) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        *(npy_double *)dataptr[nop] = (temp +
                                           (*(npy_double *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_double *)data_out)[0] = ((npy_double *)data0)[0] +
                                         ((npy_double *)data_out)[0];
        ((npy_double *)data_out)[1] = ((npy_double *)data0)[1] +
                                         ((npy_double *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
double_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data_out = (npy_double *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_double *)data_out + 2*6)[0] =
                                    ((npy_double *)data0 + 2*6)[0] +
                                    ((npy_double *)data_out + 2*6)[0];
            ((npy_double *)data_out + 2*6)[1] =
                                    ((npy_double *)data0 + 2*6)[1] +
                                    ((npy_double *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_double *)data_out + 2*5)[0] =
                                    ((npy_double *)data0 + 2*5)[0] +
                                    ((npy_double *)data_out + 2*5)[0];
            ((npy_double *)data_out + 2*5)[1] =
                                    ((npy_double *)data0 + 2*5)[1] +
                                    ((npy_double *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_double *)data_out + 2*4)[0] =
                                    ((npy_double *)data0 + 2*4)[0] +
                                    ((npy_double *)data_out + 2*4)[0];
            ((npy_double *)data_out + 2*4)[1] =
                                    ((npy_double *)data0 + 2*4)[1] +
                                    ((npy_double *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_double *)data_out + 2*3)[0] =
                                    ((npy_double *)data0 + 2*3)[0] +
                                    ((npy_double *)data_out + 2*3)[0];
            ((npy_double *)data_out + 2*3)[1] =
                                    ((npy_double *)data0 + 2*3)[1] +
                                    ((npy_double *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_double *)data_out + 2*2)[0] =
                                    ((npy_double *)data0 + 2*2)[0] +
                                    ((npy_double *)data_out + 2*2)[0];
            ((npy_double *)data_out + 2*2)[1] =
                                    ((npy_double *)data0 + 2*2)[1] +
                                    ((npy_double *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_double *)data_out + 2*1)[0] =
                                    ((npy_double *)data0 + 2*1)[0] +
                                    ((npy_double *)data_out + 2*1)[0];
            ((npy_double *)data_out + 2*1)[1] =
                                    ((npy_double *)data0 + 2*1)[1] +
                                    ((npy_double *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_double *)data_out + 2*0)[0] =
                                    ((npy_double *)data0 + 2*0)[0] +
                                    ((npy_double *)data_out + 2*0)[0];
            ((npy_double *)data_out + 2*0)[1] =
                                    ((npy_double *)data0 + 2*0)[1] +
                                    ((npy_double *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_double *)data_out + 2*0)[0] =
                                ((npy_double *)data0 + 2*0)[0] +
                                ((npy_double *)data_out + 2*0)[0];
        ((npy_double *)data_out + 2*0)[1] =
                                ((npy_double *)data0 + 2*0)[1] +
                                ((npy_double *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_double *)data_out + 2*1)[0] =
                                ((npy_double *)data0 + 2*1)[0] +
                                ((npy_double *)data_out + 2*1)[0];
        ((npy_double *)data_out + 2*1)[1] =
                                ((npy_double *)data0 + 2*1)[1] +
                                ((npy_double *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_double *)data_out + 2*2)[0] =
                                ((npy_double *)data0 + 2*2)[0] +
                                ((npy_double *)data_out + 2*2)[0];
        ((npy_double *)data_out + 2*2)[1] =
                                ((npy_double *)data0 + 2*2)[1] +
                                ((npy_double *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_double *)data_out + 2*3)[0] =
                                ((npy_double *)data0 + 2*3)[0] +
                                ((npy_double *)data_out + 2*3)[0];
        ((npy_double *)data_out + 2*3)[1] =
                                ((npy_double *)data0 + 2*3)[1] +
                                ((npy_double *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_double *)data_out + 2*4)[0] =
                                ((npy_double *)data0 + 2*4)[0] +
                                ((npy_double *)data_out + 2*4)[0];
        ((npy_double *)data_out + 2*4)[1] =
                                ((npy_double *)data0 + 2*4)[1] +
                                ((npy_double *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_double *)data_out + 2*5)[0] =
                                ((npy_double *)data0 + 2*5)[0] +
                                ((npy_double *)data_out + 2*5)[0];
        ((npy_double *)data_out + 2*5)[1] =
                                ((npy_double *)data0 + 2*5)[1] +
                                ((npy_double *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_double *)data_out + 2*6)[0] =
                                ((npy_double *)data0 + 2*6)[0] +
                                ((npy_double *)data_out + 2*6)[0];
        ((npy_double *)data_out + 2*6)[1] =
                                ((npy_double *)data0 + 2*6)[1] +
                                ((npy_double *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_double *)data_out + 2*7)[0] =
                                ((npy_double *)data0 + 2*7)[0] +
                                ((npy_double *)data_out + 2*7)[0];
        ((npy_double *)data_out + 2*7)[1] =
                                ((npy_double *)data0 + 2*7)[1] +
                                ((npy_double *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
double_sum_of_products_muladd(npy_double *data, npy_double *data_out, npy_double scalar, npy_intp count)
{
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;
    const npyv_f64 v_scalar = npyv_setall_f64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_loada_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_loada_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_loada_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_loada_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_load_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_load_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_load_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_load_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        npyv_f64 b = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_double b0 = (data[0]);
        const npy_double c0 = (data_out[0]);
        
#line 340
        const npy_double b1 = (data[1]);
        const npy_double c1 = (data_out[1]);
        
#line 340
        const npy_double b2 = (data[2]);
        const npy_double c2 = (data_out[2]);
        
#line 340
        const npy_double b3 = (data[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 346
        const npy_double abc0 = scalar * b0 + c0;
        
#line 346
        const npy_double abc1 = scalar * b1 + c1;
        
#line 346
        const npy_double abc2 = scalar * b2 + c2;
        
#line 346
        const npy_double abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_double b = (*data);
        const npy_double c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_double
}

static void
double_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data_out = (npy_double *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_double
#if NPY_SIMD_F64
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        npyv_f64 c = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_double a0 = (data0[0]);
        const npy_double b0 = (data1[0]);
        const npy_double c0 = (data_out[0]);
        
#line 420
        const npy_double a1 = (data0[1]);
        const npy_double b1 = (data1[1]);
        const npy_double c1 = (data_out[1]);
        
#line 420
        const npy_double a2 = (data0[2]);
        const npy_double b2 = (data1[2]);
        const npy_double c2 = (data_out[2]);
        
#line 420
        const npy_double a3 = (data0[3]);
        const npy_double b3 = (data1[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 427
        const npy_double abc0 = a0 * b0 + c0;
        
#line 427
        const npy_double abc1 = a1 * b1 + c1;
        
#line 427
        const npy_double abc2 = a2 * b2 + c2;
        
#line 427
        const npy_double abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        const npy_double c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_double

}

/* Some extra specializations for the two operand case */
static void
double_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value0 = (*(npy_double *)dataptr[0]);
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data_out = (npy_double *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    double_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
double_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value1 = (*(npy_double *)dataptr[1]);
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data_out = (npy_double *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    double_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double accum = 0;

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        v_accum = npyv_muladd_f64(a, b, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_double ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_double ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_double ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_double ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_double
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double value0 = (*(npy_double *)dataptr[0]);
    npy_double accum = double_sum_of_arr(data1, count);
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double value1 = (*(npy_double *)dataptr[1]);
    npy_double accum = double_sum_of_arr(data0, count);
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
double_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data2 = (npy_double *)dataptr[2];
    npy_double *data_out = (npy_double *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
double_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        *(npy_double *)dataptr[nop] = (temp +
                                           (*(npy_double *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_double);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_double);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_double *data = (npy_double *)dataptr[0];
    npy_double accum = double_sum_of_arr(data, count);
    *((npy_double *)dataptr[1]) = (accum + (*((npy_double *)dataptr[1])));
#else
    npy_double accum_re = 0, accum_im = 0;
    npy_double *data0 = (npy_double *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_double re01 = data0[0] + data0[2];
        const npy_double re23 = data0[4] + data0[6];
        const npy_double im13 = data0[1] + data0[3];
        const npy_double im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
double_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_double accum_re = 0, accum_im = 0;
#else
    npy_double accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_double *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_double *)data0) *
                 (*(npy_double *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_double *)data0) *
                 (*(npy_double *)data1) *
                 (*(npy_double *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_double *)data0)[0];
        accum_im += ((npy_double *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#  else
    ((npy_double *)dataptr[nop])[0] += accum_re;
    ((npy_double *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_double *)dataptr[1]) = (accum +
                                    (*((npy_double *)dataptr[1])));
#  else
    *((npy_double *)dataptr[nop]) = (accum +
                                    (*((npy_double *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
double_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_double *)data_out = ((*(npy_double *)data0) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_double *)data_out = ((*(npy_double *)data0) *
                                         (*(npy_double *)data1) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_double *)data_out = ((*(npy_double *)data0) *
                                         (*(npy_double *)data1) *
                                         (*(npy_double *)data2) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        *(npy_double *)dataptr[nop] = (temp +
                                           (*(npy_double *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_double *)data_out)[0] = ((npy_double *)data0)[0] +
                                         ((npy_double *)data_out)[0];
        ((npy_double *)data_out)[1] = ((npy_double *)data0)[1] +
                                         ((npy_double *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
double_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data_out = (npy_double *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_double *)data_out + 2*6)[0] =
                                    ((npy_double *)data0 + 2*6)[0] +
                                    ((npy_double *)data_out + 2*6)[0];
            ((npy_double *)data_out + 2*6)[1] =
                                    ((npy_double *)data0 + 2*6)[1] +
                                    ((npy_double *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_double *)data_out + 2*5)[0] =
                                    ((npy_double *)data0 + 2*5)[0] +
                                    ((npy_double *)data_out + 2*5)[0];
            ((npy_double *)data_out + 2*5)[1] =
                                    ((npy_double *)data0 + 2*5)[1] +
                                    ((npy_double *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_double *)data_out + 2*4)[0] =
                                    ((npy_double *)data0 + 2*4)[0] +
                                    ((npy_double *)data_out + 2*4)[0];
            ((npy_double *)data_out + 2*4)[1] =
                                    ((npy_double *)data0 + 2*4)[1] +
                                    ((npy_double *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_double *)data_out + 2*3)[0] =
                                    ((npy_double *)data0 + 2*3)[0] +
                                    ((npy_double *)data_out + 2*3)[0];
            ((npy_double *)data_out + 2*3)[1] =
                                    ((npy_double *)data0 + 2*3)[1] +
                                    ((npy_double *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_double *)data_out + 2*2)[0] =
                                    ((npy_double *)data0 + 2*2)[0] +
                                    ((npy_double *)data_out + 2*2)[0];
            ((npy_double *)data_out + 2*2)[1] =
                                    ((npy_double *)data0 + 2*2)[1] +
                                    ((npy_double *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_double *)data_out + 2*1)[0] =
                                    ((npy_double *)data0 + 2*1)[0] +
                                    ((npy_double *)data_out + 2*1)[0];
            ((npy_double *)data_out + 2*1)[1] =
                                    ((npy_double *)data0 + 2*1)[1] +
                                    ((npy_double *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_double *)data_out + 2*0)[0] =
                                    ((npy_double *)data0 + 2*0)[0] +
                                    ((npy_double *)data_out + 2*0)[0];
            ((npy_double *)data_out + 2*0)[1] =
                                    ((npy_double *)data0 + 2*0)[1] +
                                    ((npy_double *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_double *)data_out + 2*0)[0] =
                                ((npy_double *)data0 + 2*0)[0] +
                                ((npy_double *)data_out + 2*0)[0];
        ((npy_double *)data_out + 2*0)[1] =
                                ((npy_double *)data0 + 2*0)[1] +
                                ((npy_double *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_double *)data_out + 2*1)[0] =
                                ((npy_double *)data0 + 2*1)[0] +
                                ((npy_double *)data_out + 2*1)[0];
        ((npy_double *)data_out + 2*1)[1] =
                                ((npy_double *)data0 + 2*1)[1] +
                                ((npy_double *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_double *)data_out + 2*2)[0] =
                                ((npy_double *)data0 + 2*2)[0] +
                                ((npy_double *)data_out + 2*2)[0];
        ((npy_double *)data_out + 2*2)[1] =
                                ((npy_double *)data0 + 2*2)[1] +
                                ((npy_double *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_double *)data_out + 2*3)[0] =
                                ((npy_double *)data0 + 2*3)[0] +
                                ((npy_double *)data_out + 2*3)[0];
        ((npy_double *)data_out + 2*3)[1] =
                                ((npy_double *)data0 + 2*3)[1] +
                                ((npy_double *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_double *)data_out + 2*4)[0] =
                                ((npy_double *)data0 + 2*4)[0] +
                                ((npy_double *)data_out + 2*4)[0];
        ((npy_double *)data_out + 2*4)[1] =
                                ((npy_double *)data0 + 2*4)[1] +
                                ((npy_double *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_double *)data_out + 2*5)[0] =
                                ((npy_double *)data0 + 2*5)[0] +
                                ((npy_double *)data_out + 2*5)[0];
        ((npy_double *)data_out + 2*5)[1] =
                                ((npy_double *)data0 + 2*5)[1] +
                                ((npy_double *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_double *)data_out + 2*6)[0] =
                                ((npy_double *)data0 + 2*6)[0] +
                                ((npy_double *)data_out + 2*6)[0];
        ((npy_double *)data_out + 2*6)[1] =
                                ((npy_double *)data0 + 2*6)[1] +
                                ((npy_double *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_double *)data_out + 2*7)[0] =
                                ((npy_double *)data0 + 2*7)[0] +
                                ((npy_double *)data_out + 2*7)[0];
        ((npy_double *)data_out + 2*7)[1] =
                                ((npy_double *)data0 + 2*7)[1] +
                                ((npy_double *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
double_sum_of_products_muladd(npy_double *data, npy_double *data_out, npy_double scalar, npy_intp count)
{
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;
    const npyv_f64 v_scalar = npyv_setall_f64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_loada_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_loada_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_loada_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_loada_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_load_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_load_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_load_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_load_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        npyv_f64 b = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_double b0 = (data[0]);
        const npy_double c0 = (data_out[0]);
        
#line 340
        const npy_double b1 = (data[1]);
        const npy_double c1 = (data_out[1]);
        
#line 340
        const npy_double b2 = (data[2]);
        const npy_double c2 = (data_out[2]);
        
#line 340
        const npy_double b3 = (data[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 346
        const npy_double abc0 = scalar * b0 + c0;
        
#line 346
        const npy_double abc1 = scalar * b1 + c1;
        
#line 346
        const npy_double abc2 = scalar * b2 + c2;
        
#line 346
        const npy_double abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_double b = (*data);
        const npy_double c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_double
}

static void
double_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data_out = (npy_double *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_double
#if NPY_SIMD_F64
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        npyv_f64 c = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_double a0 = (data0[0]);
        const npy_double b0 = (data1[0]);
        const npy_double c0 = (data_out[0]);
        
#line 420
        const npy_double a1 = (data0[1]);
        const npy_double b1 = (data1[1]);
        const npy_double c1 = (data_out[1]);
        
#line 420
        const npy_double a2 = (data0[2]);
        const npy_double b2 = (data1[2]);
        const npy_double c2 = (data_out[2]);
        
#line 420
        const npy_double a3 = (data0[3]);
        const npy_double b3 = (data1[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 427
        const npy_double abc0 = a0 * b0 + c0;
        
#line 427
        const npy_double abc1 = a1 * b1 + c1;
        
#line 427
        const npy_double abc2 = a2 * b2 + c2;
        
#line 427
        const npy_double abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        const npy_double c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_double

}

/* Some extra specializations for the two operand case */
static void
double_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value0 = (*(npy_double *)dataptr[0]);
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data_out = (npy_double *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    double_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
double_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value1 = (*(npy_double *)dataptr[1]);
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data_out = (npy_double *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    double_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double accum = 0;

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        v_accum = npyv_muladd_f64(a, b, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_double ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_double ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_double ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_double ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_double
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double value0 = (*(npy_double *)dataptr[0]);
    npy_double accum = double_sum_of_arr(data1, count);
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double value1 = (*(npy_double *)dataptr[1]);
    npy_double accum = double_sum_of_arr(data0, count);
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
double_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data2 = (npy_double *)dataptr[2];
    npy_double *data_out = (npy_double *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
double_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        *(npy_double *)dataptr[nop] = (temp +
                                           (*(npy_double *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_double);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_double);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_double *data = (npy_double *)dataptr[0];
    npy_double accum = double_sum_of_arr(data, count);
    *((npy_double *)dataptr[1]) = (accum + (*((npy_double *)dataptr[1])));
#else
    npy_double accum_re = 0, accum_im = 0;
    npy_double *data0 = (npy_double *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_double re01 = data0[0] + data0[2];
        const npy_double re23 = data0[4] + data0[6];
        const npy_double im13 = data0[1] + data0[3];
        const npy_double im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
double_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_double accum_re = 0, accum_im = 0;
#else
    npy_double accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_double *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_double *)data0) *
                 (*(npy_double *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_double *)data0) *
                 (*(npy_double *)data1) *
                 (*(npy_double *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_double *)data0)[0];
        accum_im += ((npy_double *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_double *)dataptr[2])[0] += accum_re;
    ((npy_double *)dataptr[2])[1] += accum_im;
#  else
    ((npy_double *)dataptr[nop])[0] += accum_re;
    ((npy_double *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_double *)dataptr[2]) = (accum +
                                    (*((npy_double *)dataptr[2])));
#  else
    *((npy_double *)dataptr[nop]) = (accum +
                                    (*((npy_double *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
double_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_double *)data_out = ((*(npy_double *)data0) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_double *)data_out = ((*(npy_double *)data0) *
                                         (*(npy_double *)data1) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_double *)data_out = ((*(npy_double *)data0) *
                                         (*(npy_double *)data1) *
                                         (*(npy_double *)data2) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        *(npy_double *)dataptr[nop] = (temp +
                                           (*(npy_double *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_double *)data_out)[0] = ((npy_double *)data0)[0] +
                                         ((npy_double *)data_out)[0];
        ((npy_double *)data_out)[1] = ((npy_double *)data0)[1] +
                                         ((npy_double *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
double_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data_out = (npy_double *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_double *)data_out + 2*6)[0] =
                                    ((npy_double *)data0 + 2*6)[0] +
                                    ((npy_double *)data_out + 2*6)[0];
            ((npy_double *)data_out + 2*6)[1] =
                                    ((npy_double *)data0 + 2*6)[1] +
                                    ((npy_double *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_double *)data_out + 2*5)[0] =
                                    ((npy_double *)data0 + 2*5)[0] +
                                    ((npy_double *)data_out + 2*5)[0];
            ((npy_double *)data_out + 2*5)[1] =
                                    ((npy_double *)data0 + 2*5)[1] +
                                    ((npy_double *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_double *)data_out + 2*4)[0] =
                                    ((npy_double *)data0 + 2*4)[0] +
                                    ((npy_double *)data_out + 2*4)[0];
            ((npy_double *)data_out + 2*4)[1] =
                                    ((npy_double *)data0 + 2*4)[1] +
                                    ((npy_double *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_double *)data_out + 2*3)[0] =
                                    ((npy_double *)data0 + 2*3)[0] +
                                    ((npy_double *)data_out + 2*3)[0];
            ((npy_double *)data_out + 2*3)[1] =
                                    ((npy_double *)data0 + 2*3)[1] +
                                    ((npy_double *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_double *)data_out + 2*2)[0] =
                                    ((npy_double *)data0 + 2*2)[0] +
                                    ((npy_double *)data_out + 2*2)[0];
            ((npy_double *)data_out + 2*2)[1] =
                                    ((npy_double *)data0 + 2*2)[1] +
                                    ((npy_double *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_double *)data_out + 2*1)[0] =
                                    ((npy_double *)data0 + 2*1)[0] +
                                    ((npy_double *)data_out + 2*1)[0];
            ((npy_double *)data_out + 2*1)[1] =
                                    ((npy_double *)data0 + 2*1)[1] +
                                    ((npy_double *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_double *)data_out + 2*0)[0] =
                                    ((npy_double *)data0 + 2*0)[0] +
                                    ((npy_double *)data_out + 2*0)[0];
            ((npy_double *)data_out + 2*0)[1] =
                                    ((npy_double *)data0 + 2*0)[1] +
                                    ((npy_double *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_double *)data_out + 2*0)[0] =
                                ((npy_double *)data0 + 2*0)[0] +
                                ((npy_double *)data_out + 2*0)[0];
        ((npy_double *)data_out + 2*0)[1] =
                                ((npy_double *)data0 + 2*0)[1] +
                                ((npy_double *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_double *)data_out + 2*1)[0] =
                                ((npy_double *)data0 + 2*1)[0] +
                                ((npy_double *)data_out + 2*1)[0];
        ((npy_double *)data_out + 2*1)[1] =
                                ((npy_double *)data0 + 2*1)[1] +
                                ((npy_double *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_double *)data_out + 2*2)[0] =
                                ((npy_double *)data0 + 2*2)[0] +
                                ((npy_double *)data_out + 2*2)[0];
        ((npy_double *)data_out + 2*2)[1] =
                                ((npy_double *)data0 + 2*2)[1] +
                                ((npy_double *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_double *)data_out + 2*3)[0] =
                                ((npy_double *)data0 + 2*3)[0] +
                                ((npy_double *)data_out + 2*3)[0];
        ((npy_double *)data_out + 2*3)[1] =
                                ((npy_double *)data0 + 2*3)[1] +
                                ((npy_double *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_double *)data_out + 2*4)[0] =
                                ((npy_double *)data0 + 2*4)[0] +
                                ((npy_double *)data_out + 2*4)[0];
        ((npy_double *)data_out + 2*4)[1] =
                                ((npy_double *)data0 + 2*4)[1] +
                                ((npy_double *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_double *)data_out + 2*5)[0] =
                                ((npy_double *)data0 + 2*5)[0] +
                                ((npy_double *)data_out + 2*5)[0];
        ((npy_double *)data_out + 2*5)[1] =
                                ((npy_double *)data0 + 2*5)[1] +
                                ((npy_double *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_double *)data_out + 2*6)[0] =
                                ((npy_double *)data0 + 2*6)[0] +
                                ((npy_double *)data_out + 2*6)[0];
        ((npy_double *)data_out + 2*6)[1] =
                                ((npy_double *)data0 + 2*6)[1] +
                                ((npy_double *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_double *)data_out + 2*7)[0] =
                                ((npy_double *)data0 + 2*7)[0] +
                                ((npy_double *)data_out + 2*7)[0];
        ((npy_double *)data_out + 2*7)[1] =
                                ((npy_double *)data0 + 2*7)[1] +
                                ((npy_double *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
double_sum_of_products_muladd(npy_double *data, npy_double *data_out, npy_double scalar, npy_intp count)
{
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;
    const npyv_f64 v_scalar = npyv_setall_f64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_loada_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_loada_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_loada_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_loada_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_load_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_load_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_load_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_load_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        npyv_f64 b = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_double b0 = (data[0]);
        const npy_double c0 = (data_out[0]);
        
#line 340
        const npy_double b1 = (data[1]);
        const npy_double c1 = (data_out[1]);
        
#line 340
        const npy_double b2 = (data[2]);
        const npy_double c2 = (data_out[2]);
        
#line 340
        const npy_double b3 = (data[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 346
        const npy_double abc0 = scalar * b0 + c0;
        
#line 346
        const npy_double abc1 = scalar * b1 + c1;
        
#line 346
        const npy_double abc2 = scalar * b2 + c2;
        
#line 346
        const npy_double abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_double b = (*data);
        const npy_double c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_double
}

static void
double_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data_out = (npy_double *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_double
#if NPY_SIMD_F64
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        npyv_f64 c = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_double a0 = (data0[0]);
        const npy_double b0 = (data1[0]);
        const npy_double c0 = (data_out[0]);
        
#line 420
        const npy_double a1 = (data0[1]);
        const npy_double b1 = (data1[1]);
        const npy_double c1 = (data_out[1]);
        
#line 420
        const npy_double a2 = (data0[2]);
        const npy_double b2 = (data1[2]);
        const npy_double c2 = (data_out[2]);
        
#line 420
        const npy_double a3 = (data0[3]);
        const npy_double b3 = (data1[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 427
        const npy_double abc0 = a0 * b0 + c0;
        
#line 427
        const npy_double abc1 = a1 * b1 + c1;
        
#line 427
        const npy_double abc2 = a2 * b2 + c2;
        
#line 427
        const npy_double abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        const npy_double c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_double

}

/* Some extra specializations for the two operand case */
static void
double_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value0 = (*(npy_double *)dataptr[0]);
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data_out = (npy_double *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    double_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
double_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value1 = (*(npy_double *)dataptr[1]);
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data_out = (npy_double *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    double_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double accum = 0;

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        v_accum = npyv_muladd_f64(a, b, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_double ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_double ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_double ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_double ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_double
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double value0 = (*(npy_double *)dataptr[0]);
    npy_double accum = double_sum_of_arr(data1, count);
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double value1 = (*(npy_double *)dataptr[1]);
    npy_double accum = double_sum_of_arr(data0, count);
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
double_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data2 = (npy_double *)dataptr[2];
    npy_double *data_out = (npy_double *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
double_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        *(npy_double *)dataptr[nop] = (temp +
                                           (*(npy_double *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_double);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_double);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_double *data = (npy_double *)dataptr[0];
    npy_double accum = double_sum_of_arr(data, count);
    *((npy_double *)dataptr[1]) = (accum + (*((npy_double *)dataptr[1])));
#else
    npy_double accum_re = 0, accum_im = 0;
    npy_double *data0 = (npy_double *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_double re01 = data0[0] + data0[2];
        const npy_double re23 = data0[4] + data0[6];
        const npy_double im13 = data0[1] + data0[3];
        const npy_double im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
double_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_double accum_re = 0, accum_im = 0;
#else
    npy_double accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_double *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_double *)data0) *
                 (*(npy_double *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_double *)data0) *
                 (*(npy_double *)data1) *
                 (*(npy_double *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_double *)data0)[0];
        accum_im += ((npy_double *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_double *)dataptr[3])[0] += accum_re;
    ((npy_double *)dataptr[3])[1] += accum_im;
#  else
    ((npy_double *)dataptr[nop])[0] += accum_re;
    ((npy_double *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_double *)dataptr[3]) = (accum +
                                    (*((npy_double *)dataptr[3])));
#  else
    *((npy_double *)dataptr[nop]) = (accum +
                                    (*((npy_double *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
double_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_double *)data_out = ((*(npy_double *)data0) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_double *)data_out = ((*(npy_double *)data0) *
                                         (*(npy_double *)data1) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_double *)data_out = ((*(npy_double *)data0) *
                                         (*(npy_double *)data1) *
                                         (*(npy_double *)data2) +
                                         (*(npy_double *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        *(npy_double *)dataptr[nop] = (temp +
                                           (*(npy_double *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_double *)data_out)[0] = ((npy_double *)data0)[0] +
                                         ((npy_double *)data_out)[0];
        ((npy_double *)data_out)[1] = ((npy_double *)data0)[1] +
                                         ((npy_double *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
double_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data_out = (npy_double *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_double *)data_out + 2*6)[0] =
                                    ((npy_double *)data0 + 2*6)[0] +
                                    ((npy_double *)data_out + 2*6)[0];
            ((npy_double *)data_out + 2*6)[1] =
                                    ((npy_double *)data0 + 2*6)[1] +
                                    ((npy_double *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_double *)data_out + 2*5)[0] =
                                    ((npy_double *)data0 + 2*5)[0] +
                                    ((npy_double *)data_out + 2*5)[0];
            ((npy_double *)data_out + 2*5)[1] =
                                    ((npy_double *)data0 + 2*5)[1] +
                                    ((npy_double *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_double *)data_out + 2*4)[0] =
                                    ((npy_double *)data0 + 2*4)[0] +
                                    ((npy_double *)data_out + 2*4)[0];
            ((npy_double *)data_out + 2*4)[1] =
                                    ((npy_double *)data0 + 2*4)[1] +
                                    ((npy_double *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_double *)data_out + 2*3)[0] =
                                    ((npy_double *)data0 + 2*3)[0] +
                                    ((npy_double *)data_out + 2*3)[0];
            ((npy_double *)data_out + 2*3)[1] =
                                    ((npy_double *)data0 + 2*3)[1] +
                                    ((npy_double *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_double *)data_out + 2*2)[0] =
                                    ((npy_double *)data0 + 2*2)[0] +
                                    ((npy_double *)data_out + 2*2)[0];
            ((npy_double *)data_out + 2*2)[1] =
                                    ((npy_double *)data0 + 2*2)[1] +
                                    ((npy_double *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_double *)data_out + 2*1)[0] =
                                    ((npy_double *)data0 + 2*1)[0] +
                                    ((npy_double *)data_out + 2*1)[0];
            ((npy_double *)data_out + 2*1)[1] =
                                    ((npy_double *)data0 + 2*1)[1] +
                                    ((npy_double *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_double *)data_out + 2*0)[0] =
                                    ((npy_double *)data0 + 2*0)[0] +
                                    ((npy_double *)data_out + 2*0)[0];
            ((npy_double *)data_out + 2*0)[1] =
                                    ((npy_double *)data0 + 2*0)[1] +
                                    ((npy_double *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_double *)data_out + 2*0)[0] =
                                ((npy_double *)data0 + 2*0)[0] +
                                ((npy_double *)data_out + 2*0)[0];
        ((npy_double *)data_out + 2*0)[1] =
                                ((npy_double *)data0 + 2*0)[1] +
                                ((npy_double *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_double *)data_out + 2*1)[0] =
                                ((npy_double *)data0 + 2*1)[0] +
                                ((npy_double *)data_out + 2*1)[0];
        ((npy_double *)data_out + 2*1)[1] =
                                ((npy_double *)data0 + 2*1)[1] +
                                ((npy_double *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_double *)data_out + 2*2)[0] =
                                ((npy_double *)data0 + 2*2)[0] +
                                ((npy_double *)data_out + 2*2)[0];
        ((npy_double *)data_out + 2*2)[1] =
                                ((npy_double *)data0 + 2*2)[1] +
                                ((npy_double *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_double *)data_out + 2*3)[0] =
                                ((npy_double *)data0 + 2*3)[0] +
                                ((npy_double *)data_out + 2*3)[0];
        ((npy_double *)data_out + 2*3)[1] =
                                ((npy_double *)data0 + 2*3)[1] +
                                ((npy_double *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_double *)data_out + 2*4)[0] =
                                ((npy_double *)data0 + 2*4)[0] +
                                ((npy_double *)data_out + 2*4)[0];
        ((npy_double *)data_out + 2*4)[1] =
                                ((npy_double *)data0 + 2*4)[1] +
                                ((npy_double *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_double *)data_out + 2*5)[0] =
                                ((npy_double *)data0 + 2*5)[0] +
                                ((npy_double *)data_out + 2*5)[0];
        ((npy_double *)data_out + 2*5)[1] =
                                ((npy_double *)data0 + 2*5)[1] +
                                ((npy_double *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_double *)data_out + 2*6)[0] =
                                ((npy_double *)data0 + 2*6)[0] +
                                ((npy_double *)data_out + 2*6)[0];
        ((npy_double *)data_out + 2*6)[1] =
                                ((npy_double *)data0 + 2*6)[1] +
                                ((npy_double *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_double *)data_out + 2*7)[0] =
                                ((npy_double *)data0 + 2*7)[0] +
                                ((npy_double *)data_out + 2*7)[0];
        ((npy_double *)data_out + 2*7)[1] =
                                ((npy_double *)data0 + 2*7)[1] +
                                ((npy_double *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
double_sum_of_products_muladd(npy_double *data, npy_double *data_out, npy_double scalar, npy_intp count)
{
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;
    const npyv_f64 v_scalar = npyv_setall_f64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_loada_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_loada_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_loada_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_loada_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_load_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_load_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_load_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_load_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        npyv_f64 b = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_double b0 = (data[0]);
        const npy_double c0 = (data_out[0]);
        
#line 340
        const npy_double b1 = (data[1]);
        const npy_double c1 = (data_out[1]);
        
#line 340
        const npy_double b2 = (data[2]);
        const npy_double c2 = (data_out[2]);
        
#line 340
        const npy_double b3 = (data[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 346
        const npy_double abc0 = scalar * b0 + c0;
        
#line 346
        const npy_double abc1 = scalar * b1 + c1;
        
#line 346
        const npy_double abc2 = scalar * b2 + c2;
        
#line 346
        const npy_double abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_double b = (*data);
        const npy_double c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_double
}

static void
double_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data_out = (npy_double *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_double
#if NPY_SIMD_F64
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        npyv_f64 c = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_double a0 = (data0[0]);
        const npy_double b0 = (data1[0]);
        const npy_double c0 = (data_out[0]);
        
#line 420
        const npy_double a1 = (data0[1]);
        const npy_double b1 = (data1[1]);
        const npy_double c1 = (data_out[1]);
        
#line 420
        const npy_double a2 = (data0[2]);
        const npy_double b2 = (data1[2]);
        const npy_double c2 = (data_out[2]);
        
#line 420
        const npy_double a3 = (data0[3]);
        const npy_double b3 = (data1[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 427
        const npy_double abc0 = a0 * b0 + c0;
        
#line 427
        const npy_double abc1 = a1 * b1 + c1;
        
#line 427
        const npy_double abc2 = a2 * b2 + c2;
        
#line 427
        const npy_double abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        const npy_double c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_double

}

/* Some extra specializations for the two operand case */
static void
double_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value0 = (*(npy_double *)dataptr[0]);
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data_out = (npy_double *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    double_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
double_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value1 = (*(npy_double *)dataptr[1]);
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data_out = (npy_double *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    double_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double accum = 0;

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if NPY_SIMD_F64 // NPYV check for npy_double
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        v_accum = npyv_muladd_f64(a, b, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_double ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_double ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_double ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_double ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_double
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double value0 = (*(npy_double *)dataptr[0]);
    npy_double accum = double_sum_of_arr(data1, count);
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double value1 = (*(npy_double *)dataptr[1]);
    npy_double accum = double_sum_of_arr(data0, count);
    *(npy_double *)dataptr[2] = ((*(npy_double *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
double_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double *data0 = (npy_double *)dataptr[0];
    npy_double *data1 = (npy_double *)dataptr[1];
    npy_double *data2 = (npy_double *)dataptr[2];
    npy_double *data_out = (npy_double *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
double_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        *(npy_double *)dataptr[nop] = (temp +
                                           (*(npy_double *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_double);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_double);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
double_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_double *data = (npy_double *)dataptr[0];
    npy_double accum = double_sum_of_arr(data, count);
    *((npy_double *)dataptr[1]) = (accum + (*((npy_double *)dataptr[1])));
#else
    npy_double accum_re = 0, accum_im = 0;
    npy_double *data0 = (npy_double *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_double re01 = data0[0] + data0[2];
        const npy_double re23 = data0[4] + data0[6];
        const npy_double im13 = data0[1] + data0[3];
        const npy_double im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
double_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_double accum_re = 0, accum_im = 0;
#else
    npy_double accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("double_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_double *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_double *)data0) *
                 (*(npy_double *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_double *)data0) *
                 (*(npy_double *)data1) *
                 (*(npy_double *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_double temp = (*(npy_double *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_double *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_double *)data0)[0];
        accum_im += ((npy_double *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_double *)dataptr[1000])[0] += accum_re;
    ((npy_double *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_double *)dataptr[nop])[0] += accum_re;
    ((npy_double *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_double *)dataptr[1000]) = (accum +
                                    (*((npy_double *)dataptr[1000])));
#  else
    *((npy_double *)dataptr[nop]) = (accum +
                                    (*((npy_double *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !0
static NPY_GCC_OPT_3 npy_longdouble longdouble_sum_of_arr(npy_longdouble *data, npy_intp count)
{
    npy_longdouble accum = 0;
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_longdouble;
    npyv_longdouble v_accum = npyv_zero_longdouble();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_longdouble a0 = npyv_loada_longdouble(data + vstep * 0);
            
#line 96
            npyv_longdouble a1 = npyv_loada_longdouble(data + vstep * 1);
            
#line 96
            npyv_longdouble a2 = npyv_loada_longdouble(data + vstep * 2);
            
#line 96
            npyv_longdouble a3 = npyv_loada_longdouble(data + vstep * 3);
            
            npyv_longdouble a01   = npyv_add_longdouble(a0, a1);
            npyv_longdouble a23   = npyv_add_longdouble(a2, a3);
            npyv_longdouble a0123 = npyv_add_longdouble(a01, a23);
                     v_accum = npyv_add_longdouble(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_longdouble a0 = npyv_load_longdouble(data + vstep * 0);
            
#line 96
            npyv_longdouble a1 = npyv_load_longdouble(data + vstep * 1);
            
#line 96
            npyv_longdouble a2 = npyv_load_longdouble(data + vstep * 2);
            
#line 96
            npyv_longdouble a3 = npyv_load_longdouble(data + vstep * 3);
            
            npyv_longdouble a01   = npyv_add_longdouble(a0, a1);
            npyv_longdouble a23   = npyv_add_longdouble(a2, a3);
            npyv_longdouble a0123 = npyv_add_longdouble(a01, a23);
                     v_accum = npyv_add_longdouble(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data, count);
        v_accum = npyv_add_longdouble(a, v_accum);
    }
    accum = npyv_sum_longdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_longdouble a01 = (*data) + (data[1]);
        const npy_longdouble a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_longdouble
    return accum;
}
#endif

#line 131
static void
longdouble_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !0)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) *
                                         (*(npy_longdouble *)data1) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) *
                                         (*(npy_longdouble *)data1) *
                                         (*(npy_longdouble *)data2) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        *(npy_longdouble *)dataptr[nop] = (temp +
                                           (*(npy_longdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_longdouble *)data_out)[0] = ((npy_longdouble *)data0)[0] +
                                         ((npy_longdouble *)data_out)[0];
        ((npy_longdouble *)data_out)[1] = ((npy_longdouble *)data0)[1] +
                                         ((npy_longdouble *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
longdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longdouble *)data_out + 2*6)[0] =
                                    ((npy_longdouble *)data0 + 2*6)[0] +
                                    ((npy_longdouble *)data_out + 2*6)[0];
            ((npy_longdouble *)data_out + 2*6)[1] =
                                    ((npy_longdouble *)data0 + 2*6)[1] +
                                    ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longdouble *)data_out + 2*5)[0] =
                                    ((npy_longdouble *)data0 + 2*5)[0] +
                                    ((npy_longdouble *)data_out + 2*5)[0];
            ((npy_longdouble *)data_out + 2*5)[1] =
                                    ((npy_longdouble *)data0 + 2*5)[1] +
                                    ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longdouble *)data_out + 2*4)[0] =
                                    ((npy_longdouble *)data0 + 2*4)[0] +
                                    ((npy_longdouble *)data_out + 2*4)[0];
            ((npy_longdouble *)data_out + 2*4)[1] =
                                    ((npy_longdouble *)data0 + 2*4)[1] +
                                    ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longdouble *)data_out + 2*3)[0] =
                                    ((npy_longdouble *)data0 + 2*3)[0] +
                                    ((npy_longdouble *)data_out + 2*3)[0];
            ((npy_longdouble *)data_out + 2*3)[1] =
                                    ((npy_longdouble *)data0 + 2*3)[1] +
                                    ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longdouble *)data_out + 2*2)[0] =
                                    ((npy_longdouble *)data0 + 2*2)[0] +
                                    ((npy_longdouble *)data_out + 2*2)[0];
            ((npy_longdouble *)data_out + 2*2)[1] =
                                    ((npy_longdouble *)data0 + 2*2)[1] +
                                    ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longdouble *)data_out + 2*1)[0] =
                                    ((npy_longdouble *)data0 + 2*1)[0] +
                                    ((npy_longdouble *)data_out + 2*1)[0];
            ((npy_longdouble *)data_out + 2*1)[1] =
                                    ((npy_longdouble *)data0 + 2*1)[1] +
                                    ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longdouble *)data_out + 2*0)[0] =
                                    ((npy_longdouble *)data0 + 2*0)[0] +
                                    ((npy_longdouble *)data_out + 2*0)[0];
            ((npy_longdouble *)data_out + 2*0)[1] =
                                    ((npy_longdouble *)data0 + 2*0)[1] +
                                    ((npy_longdouble *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*0)[0] =
                                ((npy_longdouble *)data0 + 2*0)[0] +
                                ((npy_longdouble *)data_out + 2*0)[0];
        ((npy_longdouble *)data_out + 2*0)[1] =
                                ((npy_longdouble *)data0 + 2*0)[1] +
                                ((npy_longdouble *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*1)[0] =
                                ((npy_longdouble *)data0 + 2*1)[0] +
                                ((npy_longdouble *)data_out + 2*1)[0];
        ((npy_longdouble *)data_out + 2*1)[1] =
                                ((npy_longdouble *)data0 + 2*1)[1] +
                                ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*2)[0] =
                                ((npy_longdouble *)data0 + 2*2)[0] +
                                ((npy_longdouble *)data_out + 2*2)[0];
        ((npy_longdouble *)data_out + 2*2)[1] =
                                ((npy_longdouble *)data0 + 2*2)[1] +
                                ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*3)[0] =
                                ((npy_longdouble *)data0 + 2*3)[0] +
                                ((npy_longdouble *)data_out + 2*3)[0];
        ((npy_longdouble *)data_out + 2*3)[1] =
                                ((npy_longdouble *)data0 + 2*3)[1] +
                                ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*4)[0] =
                                ((npy_longdouble *)data0 + 2*4)[0] +
                                ((npy_longdouble *)data_out + 2*4)[0];
        ((npy_longdouble *)data_out + 2*4)[1] =
                                ((npy_longdouble *)data0 + 2*4)[1] +
                                ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*5)[0] =
                                ((npy_longdouble *)data0 + 2*5)[0] +
                                ((npy_longdouble *)data_out + 2*5)[0];
        ((npy_longdouble *)data_out + 2*5)[1] =
                                ((npy_longdouble *)data0 + 2*5)[1] +
                                ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*6)[0] =
                                ((npy_longdouble *)data0 + 2*6)[0] +
                                ((npy_longdouble *)data_out + 2*6)[0];
        ((npy_longdouble *)data_out + 2*6)[1] =
                                ((npy_longdouble *)data0 + 2*6)[1] +
                                ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*7)[0] =
                                ((npy_longdouble *)data0 + 2*7)[0] +
                                ((npy_longdouble *)data_out + 2*7)[0];
        ((npy_longdouble *)data_out + 2*7)[1] =
                                ((npy_longdouble *)data0 + 2*7)[1] +
                                ((npy_longdouble *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
longdouble_sum_of_products_muladd(npy_longdouble *data, npy_longdouble *data_out, npy_longdouble scalar, npy_intp count)
{
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_longdouble;
    const npyv_longdouble v_scalar = npyv_setall_longdouble(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_longdouble b0 = npyv_loada_longdouble(data + vstep * 0);
            npyv_longdouble c0 = npyv_loada_longdouble(data_out + vstep * 0);
            
#line 312
            npyv_longdouble b1 = npyv_loada_longdouble(data + vstep * 1);
            npyv_longdouble c1 = npyv_loada_longdouble(data_out + vstep * 1);
            
#line 312
            npyv_longdouble b2 = npyv_loada_longdouble(data + vstep * 2);
            npyv_longdouble c2 = npyv_loada_longdouble(data_out + vstep * 2);
            
#line 312
            npyv_longdouble b3 = npyv_loada_longdouble(data + vstep * 3);
            npyv_longdouble c3 = npyv_loada_longdouble(data_out + vstep * 3);
            
            #line 318
            npyv_longdouble abc0 = npyv_muladd_longdouble(v_scalar, b0, c0);
            
#line 318
            npyv_longdouble abc1 = npyv_muladd_longdouble(v_scalar, b1, c1);
            
#line 318
            npyv_longdouble abc2 = npyv_muladd_longdouble(v_scalar, b2, c2);
            
#line 318
            npyv_longdouble abc3 = npyv_muladd_longdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_longdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_longdouble b0 = npyv_load_longdouble(data + vstep * 0);
            npyv_longdouble c0 = npyv_load_longdouble(data_out + vstep * 0);
            
#line 312
            npyv_longdouble b1 = npyv_load_longdouble(data + vstep * 1);
            npyv_longdouble c1 = npyv_load_longdouble(data_out + vstep * 1);
            
#line 312
            npyv_longdouble b2 = npyv_load_longdouble(data + vstep * 2);
            npyv_longdouble c2 = npyv_load_longdouble(data_out + vstep * 2);
            
#line 312
            npyv_longdouble b3 = npyv_load_longdouble(data + vstep * 3);
            npyv_longdouble c3 = npyv_load_longdouble(data_out + vstep * 3);
            
            #line 318
            npyv_longdouble abc0 = npyv_muladd_longdouble(v_scalar, b0, c0);
            
#line 318
            npyv_longdouble abc1 = npyv_muladd_longdouble(v_scalar, b1, c1);
            
#line 318
            npyv_longdouble abc2 = npyv_muladd_longdouble(v_scalar, b2, c2);
            
#line 318
            npyv_longdouble abc3 = npyv_muladd_longdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_store_longdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data_out, count);
        npyv_store_till_longdouble(data_out, count, npyv_muladd_longdouble(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longdouble b0 = (data[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 340
        const npy_longdouble b1 = (data[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 340
        const npy_longdouble b2 = (data[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 340
        const npy_longdouble b3 = (data[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 346
        const npy_longdouble abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longdouble abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longdouble abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longdouble abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longdouble b = (*data);
        const npy_longdouble c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_longdouble
}

static void
longdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_longdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_longdouble;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_longdouble a0 = npyv_loada_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_loada_longdouble(data1 + vstep * 0);
            npyv_longdouble c0 = npyv_loada_longdouble(data_out + vstep * 0);
            
#line 390
            npyv_longdouble a1 = npyv_loada_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_loada_longdouble(data1 + vstep * 1);
            npyv_longdouble c1 = npyv_loada_longdouble(data_out + vstep * 1);
            
#line 390
            npyv_longdouble a2 = npyv_loada_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_loada_longdouble(data1 + vstep * 2);
            npyv_longdouble c2 = npyv_loada_longdouble(data_out + vstep * 2);
            
#line 390
            npyv_longdouble a3 = npyv_loada_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_loada_longdouble(data1 + vstep * 3);
            npyv_longdouble c3 = npyv_loada_longdouble(data_out + vstep * 3);
            
            #line 397
            npyv_longdouble abc0 = npyv_muladd_longdouble(a0, b0, c0);
            
#line 397
            npyv_longdouble abc1 = npyv_muladd_longdouble(a1, b1, c1);
            
#line 397
            npyv_longdouble abc2 = npyv_muladd_longdouble(a2, b2, c2);
            
#line 397
            npyv_longdouble abc3 = npyv_muladd_longdouble(a3, b3, c3);
            
            #line 402
            npyv_storea_longdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_longdouble a0 = npyv_load_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_load_longdouble(data1 + vstep * 0);
            npyv_longdouble c0 = npyv_load_longdouble(data_out + vstep * 0);
            
#line 390
            npyv_longdouble a1 = npyv_load_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_load_longdouble(data1 + vstep * 1);
            npyv_longdouble c1 = npyv_load_longdouble(data_out + vstep * 1);
            
#line 390
            npyv_longdouble a2 = npyv_load_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_load_longdouble(data1 + vstep * 2);
            npyv_longdouble c2 = npyv_load_longdouble(data_out + vstep * 2);
            
#line 390
            npyv_longdouble a3 = npyv_load_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_load_longdouble(data1 + vstep * 3);
            npyv_longdouble c3 = npyv_load_longdouble(data_out + vstep * 3);
            
            #line 397
            npyv_longdouble abc0 = npyv_muladd_longdouble(a0, b0, c0);
            
#line 397
            npyv_longdouble abc1 = npyv_muladd_longdouble(a1, b1, c1);
            
#line 397
            npyv_longdouble abc2 = npyv_muladd_longdouble(a2, b2, c2);
            
#line 397
            npyv_longdouble abc3 = npyv_muladd_longdouble(a3, b3, c3);
            
            #line 402
            npyv_store_longdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data0, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data1, count);
        npyv_longdouble c = npyv_load_tillz_longdouble(data_out, count);
        npyv_store_till_longdouble(data_out, count, npyv_muladd_longdouble(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longdouble a0 = (data0[0]);
        const npy_longdouble b0 = (data1[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 420
        const npy_longdouble a1 = (data0[1]);
        const npy_longdouble b1 = (data1[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 420
        const npy_longdouble a2 = (data0[2]);
        const npy_longdouble b2 = (data1[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 420
        const npy_longdouble a3 = (data0[3]);
        const npy_longdouble b3 = (data1[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 427
        const npy_longdouble abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longdouble abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longdouble abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longdouble abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        const npy_longdouble c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_longdouble

}

/* Some extra specializations for the two operand case */
static void
longdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value0 = (*(npy_longdouble *)dataptr[0]);
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    longdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
longdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value1 = (*(npy_longdouble *)dataptr[1]);
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    longdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble accum = 0;

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_longdouble;
    npyv_longdouble v_accum = npyv_zero_longdouble();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_longdouble a0 = npyv_loada_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_loada_longdouble(data1 + vstep * 0);
            
#line 501
            npyv_longdouble a1 = npyv_loada_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_loada_longdouble(data1 + vstep * 1);
            
#line 501
            npyv_longdouble a2 = npyv_loada_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_loada_longdouble(data1 + vstep * 2);
            
#line 501
            npyv_longdouble a3 = npyv_loada_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_loada_longdouble(data1 + vstep * 3);
            
            npyv_longdouble ab3 = npyv_muladd_longdouble(a3, b3, v_accum);
            npyv_longdouble ab2 = npyv_muladd_longdouble(a2, b2, ab3);
            npyv_longdouble ab1 = npyv_muladd_longdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_longdouble(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_longdouble a0 = npyv_load_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_load_longdouble(data1 + vstep * 0);
            
#line 501
            npyv_longdouble a1 = npyv_load_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_load_longdouble(data1 + vstep * 1);
            
#line 501
            npyv_longdouble a2 = npyv_load_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_load_longdouble(data1 + vstep * 2);
            
#line 501
            npyv_longdouble a3 = npyv_load_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_load_longdouble(data1 + vstep * 3);
            
            npyv_longdouble ab3 = npyv_muladd_longdouble(a3, b3, v_accum);
            npyv_longdouble ab2 = npyv_muladd_longdouble(a2, b2, ab3);
            npyv_longdouble ab1 = npyv_muladd_longdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_longdouble(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data0, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data1, count);
        v_accum = npyv_muladd_longdouble(a, b, v_accum);
    }
    accum = npyv_sum_longdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longdouble ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longdouble ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longdouble ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longdouble ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_longdouble
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble value0 = (*(npy_longdouble *)dataptr[0]);
    npy_longdouble accum = longdouble_sum_of_arr(data1, count);
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble value1 = (*(npy_longdouble *)dataptr[1]);
    npy_longdouble accum = longdouble_sum_of_arr(data0, count);
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !0

static void
longdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data2 = (npy_longdouble *)dataptr[2];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
longdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        *(npy_longdouble *)dataptr[nop] = (temp +
                                           (*(npy_longdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_longdouble);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_longdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_longdouble *data = (npy_longdouble *)dataptr[0];
    npy_longdouble accum = longdouble_sum_of_arr(data, count);
    *((npy_longdouble *)dataptr[1]) = (accum + (*((npy_longdouble *)dataptr[1])));
#else
    npy_longdouble accum_re = 0, accum_im = 0;
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longdouble re01 = data0[0] + data0[2];
        const npy_longdouble re23 = data0[4] + data0[6];
        const npy_longdouble im13 = data0[1] + data0[3];
        const npy_longdouble im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1 == 1 */

static void
longdouble_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_longdouble accum_re = 0, accum_im = 0;
#else
    npy_longdouble accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1 == 1
        accum += (*(npy_longdouble *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_longdouble *)data0) *
                 (*(npy_longdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_longdouble *)data0) *
                 (*(npy_longdouble *)data1) *
                 (*(npy_longdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_longdouble *)data0)[0];
        accum_im += ((npy_longdouble *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1 <= 3
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#  else
    ((npy_longdouble *)dataptr[nop])[0] += accum_re;
    ((npy_longdouble *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_longdouble *)dataptr[1]) = (accum +
                                    (*((npy_longdouble *)dataptr[1])));
#  else
    *((npy_longdouble *)dataptr[nop]) = (accum +
                                    (*((npy_longdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
longdouble_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !0)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) *
                                         (*(npy_longdouble *)data1) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) *
                                         (*(npy_longdouble *)data1) *
                                         (*(npy_longdouble *)data2) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        *(npy_longdouble *)dataptr[nop] = (temp +
                                           (*(npy_longdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_longdouble *)data_out)[0] = ((npy_longdouble *)data0)[0] +
                                         ((npy_longdouble *)data_out)[0];
        ((npy_longdouble *)data_out)[1] = ((npy_longdouble *)data0)[1] +
                                         ((npy_longdouble *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
longdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longdouble *)data_out + 2*6)[0] =
                                    ((npy_longdouble *)data0 + 2*6)[0] +
                                    ((npy_longdouble *)data_out + 2*6)[0];
            ((npy_longdouble *)data_out + 2*6)[1] =
                                    ((npy_longdouble *)data0 + 2*6)[1] +
                                    ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longdouble *)data_out + 2*5)[0] =
                                    ((npy_longdouble *)data0 + 2*5)[0] +
                                    ((npy_longdouble *)data_out + 2*5)[0];
            ((npy_longdouble *)data_out + 2*5)[1] =
                                    ((npy_longdouble *)data0 + 2*5)[1] +
                                    ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longdouble *)data_out + 2*4)[0] =
                                    ((npy_longdouble *)data0 + 2*4)[0] +
                                    ((npy_longdouble *)data_out + 2*4)[0];
            ((npy_longdouble *)data_out + 2*4)[1] =
                                    ((npy_longdouble *)data0 + 2*4)[1] +
                                    ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longdouble *)data_out + 2*3)[0] =
                                    ((npy_longdouble *)data0 + 2*3)[0] +
                                    ((npy_longdouble *)data_out + 2*3)[0];
            ((npy_longdouble *)data_out + 2*3)[1] =
                                    ((npy_longdouble *)data0 + 2*3)[1] +
                                    ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longdouble *)data_out + 2*2)[0] =
                                    ((npy_longdouble *)data0 + 2*2)[0] +
                                    ((npy_longdouble *)data_out + 2*2)[0];
            ((npy_longdouble *)data_out + 2*2)[1] =
                                    ((npy_longdouble *)data0 + 2*2)[1] +
                                    ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longdouble *)data_out + 2*1)[0] =
                                    ((npy_longdouble *)data0 + 2*1)[0] +
                                    ((npy_longdouble *)data_out + 2*1)[0];
            ((npy_longdouble *)data_out + 2*1)[1] =
                                    ((npy_longdouble *)data0 + 2*1)[1] +
                                    ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longdouble *)data_out + 2*0)[0] =
                                    ((npy_longdouble *)data0 + 2*0)[0] +
                                    ((npy_longdouble *)data_out + 2*0)[0];
            ((npy_longdouble *)data_out + 2*0)[1] =
                                    ((npy_longdouble *)data0 + 2*0)[1] +
                                    ((npy_longdouble *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*0)[0] =
                                ((npy_longdouble *)data0 + 2*0)[0] +
                                ((npy_longdouble *)data_out + 2*0)[0];
        ((npy_longdouble *)data_out + 2*0)[1] =
                                ((npy_longdouble *)data0 + 2*0)[1] +
                                ((npy_longdouble *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*1)[0] =
                                ((npy_longdouble *)data0 + 2*1)[0] +
                                ((npy_longdouble *)data_out + 2*1)[0];
        ((npy_longdouble *)data_out + 2*1)[1] =
                                ((npy_longdouble *)data0 + 2*1)[1] +
                                ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*2)[0] =
                                ((npy_longdouble *)data0 + 2*2)[0] +
                                ((npy_longdouble *)data_out + 2*2)[0];
        ((npy_longdouble *)data_out + 2*2)[1] =
                                ((npy_longdouble *)data0 + 2*2)[1] +
                                ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*3)[0] =
                                ((npy_longdouble *)data0 + 2*3)[0] +
                                ((npy_longdouble *)data_out + 2*3)[0];
        ((npy_longdouble *)data_out + 2*3)[1] =
                                ((npy_longdouble *)data0 + 2*3)[1] +
                                ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*4)[0] =
                                ((npy_longdouble *)data0 + 2*4)[0] +
                                ((npy_longdouble *)data_out + 2*4)[0];
        ((npy_longdouble *)data_out + 2*4)[1] =
                                ((npy_longdouble *)data0 + 2*4)[1] +
                                ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*5)[0] =
                                ((npy_longdouble *)data0 + 2*5)[0] +
                                ((npy_longdouble *)data_out + 2*5)[0];
        ((npy_longdouble *)data_out + 2*5)[1] =
                                ((npy_longdouble *)data0 + 2*5)[1] +
                                ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*6)[0] =
                                ((npy_longdouble *)data0 + 2*6)[0] +
                                ((npy_longdouble *)data_out + 2*6)[0];
        ((npy_longdouble *)data_out + 2*6)[1] =
                                ((npy_longdouble *)data0 + 2*6)[1] +
                                ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*7)[0] =
                                ((npy_longdouble *)data0 + 2*7)[0] +
                                ((npy_longdouble *)data_out + 2*7)[0];
        ((npy_longdouble *)data_out + 2*7)[1] =
                                ((npy_longdouble *)data0 + 2*7)[1] +
                                ((npy_longdouble *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
longdouble_sum_of_products_muladd(npy_longdouble *data, npy_longdouble *data_out, npy_longdouble scalar, npy_intp count)
{
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_longdouble;
    const npyv_longdouble v_scalar = npyv_setall_longdouble(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_longdouble b0 = npyv_loada_longdouble(data + vstep * 0);
            npyv_longdouble c0 = npyv_loada_longdouble(data_out + vstep * 0);
            
#line 312
            npyv_longdouble b1 = npyv_loada_longdouble(data + vstep * 1);
            npyv_longdouble c1 = npyv_loada_longdouble(data_out + vstep * 1);
            
#line 312
            npyv_longdouble b2 = npyv_loada_longdouble(data + vstep * 2);
            npyv_longdouble c2 = npyv_loada_longdouble(data_out + vstep * 2);
            
#line 312
            npyv_longdouble b3 = npyv_loada_longdouble(data + vstep * 3);
            npyv_longdouble c3 = npyv_loada_longdouble(data_out + vstep * 3);
            
            #line 318
            npyv_longdouble abc0 = npyv_muladd_longdouble(v_scalar, b0, c0);
            
#line 318
            npyv_longdouble abc1 = npyv_muladd_longdouble(v_scalar, b1, c1);
            
#line 318
            npyv_longdouble abc2 = npyv_muladd_longdouble(v_scalar, b2, c2);
            
#line 318
            npyv_longdouble abc3 = npyv_muladd_longdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_longdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_longdouble b0 = npyv_load_longdouble(data + vstep * 0);
            npyv_longdouble c0 = npyv_load_longdouble(data_out + vstep * 0);
            
#line 312
            npyv_longdouble b1 = npyv_load_longdouble(data + vstep * 1);
            npyv_longdouble c1 = npyv_load_longdouble(data_out + vstep * 1);
            
#line 312
            npyv_longdouble b2 = npyv_load_longdouble(data + vstep * 2);
            npyv_longdouble c2 = npyv_load_longdouble(data_out + vstep * 2);
            
#line 312
            npyv_longdouble b3 = npyv_load_longdouble(data + vstep * 3);
            npyv_longdouble c3 = npyv_load_longdouble(data_out + vstep * 3);
            
            #line 318
            npyv_longdouble abc0 = npyv_muladd_longdouble(v_scalar, b0, c0);
            
#line 318
            npyv_longdouble abc1 = npyv_muladd_longdouble(v_scalar, b1, c1);
            
#line 318
            npyv_longdouble abc2 = npyv_muladd_longdouble(v_scalar, b2, c2);
            
#line 318
            npyv_longdouble abc3 = npyv_muladd_longdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_store_longdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data_out, count);
        npyv_store_till_longdouble(data_out, count, npyv_muladd_longdouble(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longdouble b0 = (data[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 340
        const npy_longdouble b1 = (data[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 340
        const npy_longdouble b2 = (data[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 340
        const npy_longdouble b3 = (data[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 346
        const npy_longdouble abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longdouble abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longdouble abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longdouble abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longdouble b = (*data);
        const npy_longdouble c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_longdouble
}

static void
longdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_longdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_longdouble;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_longdouble a0 = npyv_loada_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_loada_longdouble(data1 + vstep * 0);
            npyv_longdouble c0 = npyv_loada_longdouble(data_out + vstep * 0);
            
#line 390
            npyv_longdouble a1 = npyv_loada_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_loada_longdouble(data1 + vstep * 1);
            npyv_longdouble c1 = npyv_loada_longdouble(data_out + vstep * 1);
            
#line 390
            npyv_longdouble a2 = npyv_loada_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_loada_longdouble(data1 + vstep * 2);
            npyv_longdouble c2 = npyv_loada_longdouble(data_out + vstep * 2);
            
#line 390
            npyv_longdouble a3 = npyv_loada_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_loada_longdouble(data1 + vstep * 3);
            npyv_longdouble c3 = npyv_loada_longdouble(data_out + vstep * 3);
            
            #line 397
            npyv_longdouble abc0 = npyv_muladd_longdouble(a0, b0, c0);
            
#line 397
            npyv_longdouble abc1 = npyv_muladd_longdouble(a1, b1, c1);
            
#line 397
            npyv_longdouble abc2 = npyv_muladd_longdouble(a2, b2, c2);
            
#line 397
            npyv_longdouble abc3 = npyv_muladd_longdouble(a3, b3, c3);
            
            #line 402
            npyv_storea_longdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_longdouble a0 = npyv_load_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_load_longdouble(data1 + vstep * 0);
            npyv_longdouble c0 = npyv_load_longdouble(data_out + vstep * 0);
            
#line 390
            npyv_longdouble a1 = npyv_load_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_load_longdouble(data1 + vstep * 1);
            npyv_longdouble c1 = npyv_load_longdouble(data_out + vstep * 1);
            
#line 390
            npyv_longdouble a2 = npyv_load_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_load_longdouble(data1 + vstep * 2);
            npyv_longdouble c2 = npyv_load_longdouble(data_out + vstep * 2);
            
#line 390
            npyv_longdouble a3 = npyv_load_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_load_longdouble(data1 + vstep * 3);
            npyv_longdouble c3 = npyv_load_longdouble(data_out + vstep * 3);
            
            #line 397
            npyv_longdouble abc0 = npyv_muladd_longdouble(a0, b0, c0);
            
#line 397
            npyv_longdouble abc1 = npyv_muladd_longdouble(a1, b1, c1);
            
#line 397
            npyv_longdouble abc2 = npyv_muladd_longdouble(a2, b2, c2);
            
#line 397
            npyv_longdouble abc3 = npyv_muladd_longdouble(a3, b3, c3);
            
            #line 402
            npyv_store_longdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data0, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data1, count);
        npyv_longdouble c = npyv_load_tillz_longdouble(data_out, count);
        npyv_store_till_longdouble(data_out, count, npyv_muladd_longdouble(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longdouble a0 = (data0[0]);
        const npy_longdouble b0 = (data1[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 420
        const npy_longdouble a1 = (data0[1]);
        const npy_longdouble b1 = (data1[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 420
        const npy_longdouble a2 = (data0[2]);
        const npy_longdouble b2 = (data1[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 420
        const npy_longdouble a3 = (data0[3]);
        const npy_longdouble b3 = (data1[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 427
        const npy_longdouble abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longdouble abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longdouble abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longdouble abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        const npy_longdouble c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_longdouble

}

/* Some extra specializations for the two operand case */
static void
longdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value0 = (*(npy_longdouble *)dataptr[0]);
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    longdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
longdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value1 = (*(npy_longdouble *)dataptr[1]);
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    longdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble accum = 0;

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_longdouble;
    npyv_longdouble v_accum = npyv_zero_longdouble();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_longdouble a0 = npyv_loada_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_loada_longdouble(data1 + vstep * 0);
            
#line 501
            npyv_longdouble a1 = npyv_loada_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_loada_longdouble(data1 + vstep * 1);
            
#line 501
            npyv_longdouble a2 = npyv_loada_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_loada_longdouble(data1 + vstep * 2);
            
#line 501
            npyv_longdouble a3 = npyv_loada_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_loada_longdouble(data1 + vstep * 3);
            
            npyv_longdouble ab3 = npyv_muladd_longdouble(a3, b3, v_accum);
            npyv_longdouble ab2 = npyv_muladd_longdouble(a2, b2, ab3);
            npyv_longdouble ab1 = npyv_muladd_longdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_longdouble(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_longdouble a0 = npyv_load_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_load_longdouble(data1 + vstep * 0);
            
#line 501
            npyv_longdouble a1 = npyv_load_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_load_longdouble(data1 + vstep * 1);
            
#line 501
            npyv_longdouble a2 = npyv_load_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_load_longdouble(data1 + vstep * 2);
            
#line 501
            npyv_longdouble a3 = npyv_load_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_load_longdouble(data1 + vstep * 3);
            
            npyv_longdouble ab3 = npyv_muladd_longdouble(a3, b3, v_accum);
            npyv_longdouble ab2 = npyv_muladd_longdouble(a2, b2, ab3);
            npyv_longdouble ab1 = npyv_muladd_longdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_longdouble(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data0, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data1, count);
        v_accum = npyv_muladd_longdouble(a, b, v_accum);
    }
    accum = npyv_sum_longdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longdouble ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longdouble ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longdouble ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longdouble ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_longdouble
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble value0 = (*(npy_longdouble *)dataptr[0]);
    npy_longdouble accum = longdouble_sum_of_arr(data1, count);
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble value1 = (*(npy_longdouble *)dataptr[1]);
    npy_longdouble accum = longdouble_sum_of_arr(data0, count);
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !0

static void
longdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data2 = (npy_longdouble *)dataptr[2];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
longdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        *(npy_longdouble *)dataptr[nop] = (temp +
                                           (*(npy_longdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_longdouble);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_longdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_longdouble *data = (npy_longdouble *)dataptr[0];
    npy_longdouble accum = longdouble_sum_of_arr(data, count);
    *((npy_longdouble *)dataptr[1]) = (accum + (*((npy_longdouble *)dataptr[1])));
#else
    npy_longdouble accum_re = 0, accum_im = 0;
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longdouble re01 = data0[0] + data0[2];
        const npy_longdouble re23 = data0[4] + data0[6];
        const npy_longdouble im13 = data0[1] + data0[3];
        const npy_longdouble im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 2 == 1 */

static void
longdouble_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_longdouble accum_re = 0, accum_im = 0;
#else
    npy_longdouble accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 2 == 1
        accum += (*(npy_longdouble *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_longdouble *)data0) *
                 (*(npy_longdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_longdouble *)data0) *
                 (*(npy_longdouble *)data1) *
                 (*(npy_longdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_longdouble *)data0)[0];
        accum_im += ((npy_longdouble *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 2 <= 3
    ((npy_longdouble *)dataptr[2])[0] += accum_re;
    ((npy_longdouble *)dataptr[2])[1] += accum_im;
#  else
    ((npy_longdouble *)dataptr[nop])[0] += accum_re;
    ((npy_longdouble *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_longdouble *)dataptr[2]) = (accum +
                                    (*((npy_longdouble *)dataptr[2])));
#  else
    *((npy_longdouble *)dataptr[nop]) = (accum +
                                    (*((npy_longdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
longdouble_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !0)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) *
                                         (*(npy_longdouble *)data1) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) *
                                         (*(npy_longdouble *)data1) *
                                         (*(npy_longdouble *)data2) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        *(npy_longdouble *)dataptr[nop] = (temp +
                                           (*(npy_longdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_longdouble *)data_out)[0] = ((npy_longdouble *)data0)[0] +
                                         ((npy_longdouble *)data_out)[0];
        ((npy_longdouble *)data_out)[1] = ((npy_longdouble *)data0)[1] +
                                         ((npy_longdouble *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
longdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longdouble *)data_out + 2*6)[0] =
                                    ((npy_longdouble *)data0 + 2*6)[0] +
                                    ((npy_longdouble *)data_out + 2*6)[0];
            ((npy_longdouble *)data_out + 2*6)[1] =
                                    ((npy_longdouble *)data0 + 2*6)[1] +
                                    ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longdouble *)data_out + 2*5)[0] =
                                    ((npy_longdouble *)data0 + 2*5)[0] +
                                    ((npy_longdouble *)data_out + 2*5)[0];
            ((npy_longdouble *)data_out + 2*5)[1] =
                                    ((npy_longdouble *)data0 + 2*5)[1] +
                                    ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longdouble *)data_out + 2*4)[0] =
                                    ((npy_longdouble *)data0 + 2*4)[0] +
                                    ((npy_longdouble *)data_out + 2*4)[0];
            ((npy_longdouble *)data_out + 2*4)[1] =
                                    ((npy_longdouble *)data0 + 2*4)[1] +
                                    ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longdouble *)data_out + 2*3)[0] =
                                    ((npy_longdouble *)data0 + 2*3)[0] +
                                    ((npy_longdouble *)data_out + 2*3)[0];
            ((npy_longdouble *)data_out + 2*3)[1] =
                                    ((npy_longdouble *)data0 + 2*3)[1] +
                                    ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longdouble *)data_out + 2*2)[0] =
                                    ((npy_longdouble *)data0 + 2*2)[0] +
                                    ((npy_longdouble *)data_out + 2*2)[0];
            ((npy_longdouble *)data_out + 2*2)[1] =
                                    ((npy_longdouble *)data0 + 2*2)[1] +
                                    ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longdouble *)data_out + 2*1)[0] =
                                    ((npy_longdouble *)data0 + 2*1)[0] +
                                    ((npy_longdouble *)data_out + 2*1)[0];
            ((npy_longdouble *)data_out + 2*1)[1] =
                                    ((npy_longdouble *)data0 + 2*1)[1] +
                                    ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longdouble *)data_out + 2*0)[0] =
                                    ((npy_longdouble *)data0 + 2*0)[0] +
                                    ((npy_longdouble *)data_out + 2*0)[0];
            ((npy_longdouble *)data_out + 2*0)[1] =
                                    ((npy_longdouble *)data0 + 2*0)[1] +
                                    ((npy_longdouble *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*0)[0] =
                                ((npy_longdouble *)data0 + 2*0)[0] +
                                ((npy_longdouble *)data_out + 2*0)[0];
        ((npy_longdouble *)data_out + 2*0)[1] =
                                ((npy_longdouble *)data0 + 2*0)[1] +
                                ((npy_longdouble *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*1)[0] =
                                ((npy_longdouble *)data0 + 2*1)[0] +
                                ((npy_longdouble *)data_out + 2*1)[0];
        ((npy_longdouble *)data_out + 2*1)[1] =
                                ((npy_longdouble *)data0 + 2*1)[1] +
                                ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*2)[0] =
                                ((npy_longdouble *)data0 + 2*2)[0] +
                                ((npy_longdouble *)data_out + 2*2)[0];
        ((npy_longdouble *)data_out + 2*2)[1] =
                                ((npy_longdouble *)data0 + 2*2)[1] +
                                ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*3)[0] =
                                ((npy_longdouble *)data0 + 2*3)[0] +
                                ((npy_longdouble *)data_out + 2*3)[0];
        ((npy_longdouble *)data_out + 2*3)[1] =
                                ((npy_longdouble *)data0 + 2*3)[1] +
                                ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*4)[0] =
                                ((npy_longdouble *)data0 + 2*4)[0] +
                                ((npy_longdouble *)data_out + 2*4)[0];
        ((npy_longdouble *)data_out + 2*4)[1] =
                                ((npy_longdouble *)data0 + 2*4)[1] +
                                ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*5)[0] =
                                ((npy_longdouble *)data0 + 2*5)[0] +
                                ((npy_longdouble *)data_out + 2*5)[0];
        ((npy_longdouble *)data_out + 2*5)[1] =
                                ((npy_longdouble *)data0 + 2*5)[1] +
                                ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*6)[0] =
                                ((npy_longdouble *)data0 + 2*6)[0] +
                                ((npy_longdouble *)data_out + 2*6)[0];
        ((npy_longdouble *)data_out + 2*6)[1] =
                                ((npy_longdouble *)data0 + 2*6)[1] +
                                ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*7)[0] =
                                ((npy_longdouble *)data0 + 2*7)[0] +
                                ((npy_longdouble *)data_out + 2*7)[0];
        ((npy_longdouble *)data_out + 2*7)[1] =
                                ((npy_longdouble *)data0 + 2*7)[1] +
                                ((npy_longdouble *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
longdouble_sum_of_products_muladd(npy_longdouble *data, npy_longdouble *data_out, npy_longdouble scalar, npy_intp count)
{
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_longdouble;
    const npyv_longdouble v_scalar = npyv_setall_longdouble(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_longdouble b0 = npyv_loada_longdouble(data + vstep * 0);
            npyv_longdouble c0 = npyv_loada_longdouble(data_out + vstep * 0);
            
#line 312
            npyv_longdouble b1 = npyv_loada_longdouble(data + vstep * 1);
            npyv_longdouble c1 = npyv_loada_longdouble(data_out + vstep * 1);
            
#line 312
            npyv_longdouble b2 = npyv_loada_longdouble(data + vstep * 2);
            npyv_longdouble c2 = npyv_loada_longdouble(data_out + vstep * 2);
            
#line 312
            npyv_longdouble b3 = npyv_loada_longdouble(data + vstep * 3);
            npyv_longdouble c3 = npyv_loada_longdouble(data_out + vstep * 3);
            
            #line 318
            npyv_longdouble abc0 = npyv_muladd_longdouble(v_scalar, b0, c0);
            
#line 318
            npyv_longdouble abc1 = npyv_muladd_longdouble(v_scalar, b1, c1);
            
#line 318
            npyv_longdouble abc2 = npyv_muladd_longdouble(v_scalar, b2, c2);
            
#line 318
            npyv_longdouble abc3 = npyv_muladd_longdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_longdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_longdouble b0 = npyv_load_longdouble(data + vstep * 0);
            npyv_longdouble c0 = npyv_load_longdouble(data_out + vstep * 0);
            
#line 312
            npyv_longdouble b1 = npyv_load_longdouble(data + vstep * 1);
            npyv_longdouble c1 = npyv_load_longdouble(data_out + vstep * 1);
            
#line 312
            npyv_longdouble b2 = npyv_load_longdouble(data + vstep * 2);
            npyv_longdouble c2 = npyv_load_longdouble(data_out + vstep * 2);
            
#line 312
            npyv_longdouble b3 = npyv_load_longdouble(data + vstep * 3);
            npyv_longdouble c3 = npyv_load_longdouble(data_out + vstep * 3);
            
            #line 318
            npyv_longdouble abc0 = npyv_muladd_longdouble(v_scalar, b0, c0);
            
#line 318
            npyv_longdouble abc1 = npyv_muladd_longdouble(v_scalar, b1, c1);
            
#line 318
            npyv_longdouble abc2 = npyv_muladd_longdouble(v_scalar, b2, c2);
            
#line 318
            npyv_longdouble abc3 = npyv_muladd_longdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_store_longdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data_out, count);
        npyv_store_till_longdouble(data_out, count, npyv_muladd_longdouble(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longdouble b0 = (data[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 340
        const npy_longdouble b1 = (data[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 340
        const npy_longdouble b2 = (data[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 340
        const npy_longdouble b3 = (data[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 346
        const npy_longdouble abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longdouble abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longdouble abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longdouble abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longdouble b = (*data);
        const npy_longdouble c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_longdouble
}

static void
longdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_longdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_longdouble;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_longdouble a0 = npyv_loada_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_loada_longdouble(data1 + vstep * 0);
            npyv_longdouble c0 = npyv_loada_longdouble(data_out + vstep * 0);
            
#line 390
            npyv_longdouble a1 = npyv_loada_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_loada_longdouble(data1 + vstep * 1);
            npyv_longdouble c1 = npyv_loada_longdouble(data_out + vstep * 1);
            
#line 390
            npyv_longdouble a2 = npyv_loada_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_loada_longdouble(data1 + vstep * 2);
            npyv_longdouble c2 = npyv_loada_longdouble(data_out + vstep * 2);
            
#line 390
            npyv_longdouble a3 = npyv_loada_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_loada_longdouble(data1 + vstep * 3);
            npyv_longdouble c3 = npyv_loada_longdouble(data_out + vstep * 3);
            
            #line 397
            npyv_longdouble abc0 = npyv_muladd_longdouble(a0, b0, c0);
            
#line 397
            npyv_longdouble abc1 = npyv_muladd_longdouble(a1, b1, c1);
            
#line 397
            npyv_longdouble abc2 = npyv_muladd_longdouble(a2, b2, c2);
            
#line 397
            npyv_longdouble abc3 = npyv_muladd_longdouble(a3, b3, c3);
            
            #line 402
            npyv_storea_longdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_longdouble a0 = npyv_load_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_load_longdouble(data1 + vstep * 0);
            npyv_longdouble c0 = npyv_load_longdouble(data_out + vstep * 0);
            
#line 390
            npyv_longdouble a1 = npyv_load_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_load_longdouble(data1 + vstep * 1);
            npyv_longdouble c1 = npyv_load_longdouble(data_out + vstep * 1);
            
#line 390
            npyv_longdouble a2 = npyv_load_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_load_longdouble(data1 + vstep * 2);
            npyv_longdouble c2 = npyv_load_longdouble(data_out + vstep * 2);
            
#line 390
            npyv_longdouble a3 = npyv_load_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_load_longdouble(data1 + vstep * 3);
            npyv_longdouble c3 = npyv_load_longdouble(data_out + vstep * 3);
            
            #line 397
            npyv_longdouble abc0 = npyv_muladd_longdouble(a0, b0, c0);
            
#line 397
            npyv_longdouble abc1 = npyv_muladd_longdouble(a1, b1, c1);
            
#line 397
            npyv_longdouble abc2 = npyv_muladd_longdouble(a2, b2, c2);
            
#line 397
            npyv_longdouble abc3 = npyv_muladd_longdouble(a3, b3, c3);
            
            #line 402
            npyv_store_longdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data0, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data1, count);
        npyv_longdouble c = npyv_load_tillz_longdouble(data_out, count);
        npyv_store_till_longdouble(data_out, count, npyv_muladd_longdouble(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longdouble a0 = (data0[0]);
        const npy_longdouble b0 = (data1[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 420
        const npy_longdouble a1 = (data0[1]);
        const npy_longdouble b1 = (data1[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 420
        const npy_longdouble a2 = (data0[2]);
        const npy_longdouble b2 = (data1[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 420
        const npy_longdouble a3 = (data0[3]);
        const npy_longdouble b3 = (data1[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 427
        const npy_longdouble abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longdouble abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longdouble abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longdouble abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        const npy_longdouble c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_longdouble

}

/* Some extra specializations for the two operand case */
static void
longdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value0 = (*(npy_longdouble *)dataptr[0]);
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    longdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
longdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value1 = (*(npy_longdouble *)dataptr[1]);
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    longdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble accum = 0;

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_longdouble;
    npyv_longdouble v_accum = npyv_zero_longdouble();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_longdouble a0 = npyv_loada_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_loada_longdouble(data1 + vstep * 0);
            
#line 501
            npyv_longdouble a1 = npyv_loada_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_loada_longdouble(data1 + vstep * 1);
            
#line 501
            npyv_longdouble a2 = npyv_loada_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_loada_longdouble(data1 + vstep * 2);
            
#line 501
            npyv_longdouble a3 = npyv_loada_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_loada_longdouble(data1 + vstep * 3);
            
            npyv_longdouble ab3 = npyv_muladd_longdouble(a3, b3, v_accum);
            npyv_longdouble ab2 = npyv_muladd_longdouble(a2, b2, ab3);
            npyv_longdouble ab1 = npyv_muladd_longdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_longdouble(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_longdouble a0 = npyv_load_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_load_longdouble(data1 + vstep * 0);
            
#line 501
            npyv_longdouble a1 = npyv_load_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_load_longdouble(data1 + vstep * 1);
            
#line 501
            npyv_longdouble a2 = npyv_load_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_load_longdouble(data1 + vstep * 2);
            
#line 501
            npyv_longdouble a3 = npyv_load_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_load_longdouble(data1 + vstep * 3);
            
            npyv_longdouble ab3 = npyv_muladd_longdouble(a3, b3, v_accum);
            npyv_longdouble ab2 = npyv_muladd_longdouble(a2, b2, ab3);
            npyv_longdouble ab1 = npyv_muladd_longdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_longdouble(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data0, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data1, count);
        v_accum = npyv_muladd_longdouble(a, b, v_accum);
    }
    accum = npyv_sum_longdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longdouble ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longdouble ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longdouble ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longdouble ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_longdouble
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble value0 = (*(npy_longdouble *)dataptr[0]);
    npy_longdouble accum = longdouble_sum_of_arr(data1, count);
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble value1 = (*(npy_longdouble *)dataptr[1]);
    npy_longdouble accum = longdouble_sum_of_arr(data0, count);
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !0

static void
longdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data2 = (npy_longdouble *)dataptr[2];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
longdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        *(npy_longdouble *)dataptr[nop] = (temp +
                                           (*(npy_longdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_longdouble);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_longdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_longdouble *data = (npy_longdouble *)dataptr[0];
    npy_longdouble accum = longdouble_sum_of_arr(data, count);
    *((npy_longdouble *)dataptr[1]) = (accum + (*((npy_longdouble *)dataptr[1])));
#else
    npy_longdouble accum_re = 0, accum_im = 0;
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longdouble re01 = data0[0] + data0[2];
        const npy_longdouble re23 = data0[4] + data0[6];
        const npy_longdouble im13 = data0[1] + data0[3];
        const npy_longdouble im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 3 == 1 */

static void
longdouble_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_longdouble accum_re = 0, accum_im = 0;
#else
    npy_longdouble accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 3 == 1
        accum += (*(npy_longdouble *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_longdouble *)data0) *
                 (*(npy_longdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_longdouble *)data0) *
                 (*(npy_longdouble *)data1) *
                 (*(npy_longdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_longdouble *)data0)[0];
        accum_im += ((npy_longdouble *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 3 <= 3
    ((npy_longdouble *)dataptr[3])[0] += accum_re;
    ((npy_longdouble *)dataptr[3])[1] += accum_im;
#  else
    ((npy_longdouble *)dataptr[nop])[0] += accum_re;
    ((npy_longdouble *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_longdouble *)dataptr[3]) = (accum +
                                    (*((npy_longdouble *)dataptr[3])));
#  else
    *((npy_longdouble *)dataptr[nop]) = (accum +
                                    (*((npy_longdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
longdouble_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !0)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) *
                                         (*(npy_longdouble *)data1) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_longdouble *)data_out = ((*(npy_longdouble *)data0) *
                                         (*(npy_longdouble *)data1) *
                                         (*(npy_longdouble *)data2) +
                                         (*(npy_longdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        *(npy_longdouble *)dataptr[nop] = (temp +
                                           (*(npy_longdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_longdouble *)data_out)[0] = ((npy_longdouble *)data0)[0] +
                                         ((npy_longdouble *)data_out)[0];
        ((npy_longdouble *)data_out)[1] = ((npy_longdouble *)data0)[1] +
                                         ((npy_longdouble *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
longdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !0
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longdouble *)data_out + 2*6)[0] =
                                    ((npy_longdouble *)data0 + 2*6)[0] +
                                    ((npy_longdouble *)data_out + 2*6)[0];
            ((npy_longdouble *)data_out + 2*6)[1] =
                                    ((npy_longdouble *)data0 + 2*6)[1] +
                                    ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !0
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longdouble *)data_out + 2*5)[0] =
                                    ((npy_longdouble *)data0 + 2*5)[0] +
                                    ((npy_longdouble *)data_out + 2*5)[0];
            ((npy_longdouble *)data_out + 2*5)[1] =
                                    ((npy_longdouble *)data0 + 2*5)[1] +
                                    ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !0
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longdouble *)data_out + 2*4)[0] =
                                    ((npy_longdouble *)data0 + 2*4)[0] +
                                    ((npy_longdouble *)data_out + 2*4)[0];
            ((npy_longdouble *)data_out + 2*4)[1] =
                                    ((npy_longdouble *)data0 + 2*4)[1] +
                                    ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !0
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longdouble *)data_out + 2*3)[0] =
                                    ((npy_longdouble *)data0 + 2*3)[0] +
                                    ((npy_longdouble *)data_out + 2*3)[0];
            ((npy_longdouble *)data_out + 2*3)[1] =
                                    ((npy_longdouble *)data0 + 2*3)[1] +
                                    ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !0
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longdouble *)data_out + 2*2)[0] =
                                    ((npy_longdouble *)data0 + 2*2)[0] +
                                    ((npy_longdouble *)data_out + 2*2)[0];
            ((npy_longdouble *)data_out + 2*2)[1] =
                                    ((npy_longdouble *)data0 + 2*2)[1] +
                                    ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !0
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longdouble *)data_out + 2*1)[0] =
                                    ((npy_longdouble *)data0 + 2*1)[0] +
                                    ((npy_longdouble *)data_out + 2*1)[0];
            ((npy_longdouble *)data_out + 2*1)[1] =
                                    ((npy_longdouble *)data0 + 2*1)[1] +
                                    ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !0
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longdouble *)data_out + 2*0)[0] =
                                    ((npy_longdouble *)data0 + 2*0)[0] +
                                    ((npy_longdouble *)data_out + 2*0)[0];
            ((npy_longdouble *)data_out + 2*0)[1] =
                                    ((npy_longdouble *)data0 + 2*0)[1] +
                                    ((npy_longdouble *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !0
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*0)[0] =
                                ((npy_longdouble *)data0 + 2*0)[0] +
                                ((npy_longdouble *)data_out + 2*0)[0];
        ((npy_longdouble *)data_out + 2*0)[1] =
                                ((npy_longdouble *)data0 + 2*0)[1] +
                                ((npy_longdouble *)data_out + 2*0)[1];
#endif

#line 270
#if !0
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*1)[0] =
                                ((npy_longdouble *)data0 + 2*1)[0] +
                                ((npy_longdouble *)data_out + 2*1)[0];
        ((npy_longdouble *)data_out + 2*1)[1] =
                                ((npy_longdouble *)data0 + 2*1)[1] +
                                ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 270
#if !0
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*2)[0] =
                                ((npy_longdouble *)data0 + 2*2)[0] +
                                ((npy_longdouble *)data_out + 2*2)[0];
        ((npy_longdouble *)data_out + 2*2)[1] =
                                ((npy_longdouble *)data0 + 2*2)[1] +
                                ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 270
#if !0
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*3)[0] =
                                ((npy_longdouble *)data0 + 2*3)[0] +
                                ((npy_longdouble *)data_out + 2*3)[0];
        ((npy_longdouble *)data_out + 2*3)[1] =
                                ((npy_longdouble *)data0 + 2*3)[1] +
                                ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 270
#if !0
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*4)[0] =
                                ((npy_longdouble *)data0 + 2*4)[0] +
                                ((npy_longdouble *)data_out + 2*4)[0];
        ((npy_longdouble *)data_out + 2*4)[1] =
                                ((npy_longdouble *)data0 + 2*4)[1] +
                                ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 270
#if !0
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*5)[0] =
                                ((npy_longdouble *)data0 + 2*5)[0] +
                                ((npy_longdouble *)data_out + 2*5)[0];
        ((npy_longdouble *)data_out + 2*5)[1] =
                                ((npy_longdouble *)data0 + 2*5)[1] +
                                ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 270
#if !0
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*6)[0] =
                                ((npy_longdouble *)data0 + 2*6)[0] +
                                ((npy_longdouble *)data_out + 2*6)[0];
        ((npy_longdouble *)data_out + 2*6)[1] =
                                ((npy_longdouble *)data0 + 2*6)[1] +
                                ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 270
#if !0
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*7)[0] =
                                ((npy_longdouble *)data0 + 2*7)[0] +
                                ((npy_longdouble *)data_out + 2*7)[0];
        ((npy_longdouble *)data_out + 2*7)[1] =
                                ((npy_longdouble *)data0 + 2*7)[1] +
                                ((npy_longdouble *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !0

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
longdouble_sum_of_products_muladd(npy_longdouble *data, npy_longdouble *data_out, npy_longdouble scalar, npy_intp count)
{
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_longdouble;
    const npyv_longdouble v_scalar = npyv_setall_longdouble(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_longdouble b0 = npyv_loada_longdouble(data + vstep * 0);
            npyv_longdouble c0 = npyv_loada_longdouble(data_out + vstep * 0);
            
#line 312
            npyv_longdouble b1 = npyv_loada_longdouble(data + vstep * 1);
            npyv_longdouble c1 = npyv_loada_longdouble(data_out + vstep * 1);
            
#line 312
            npyv_longdouble b2 = npyv_loada_longdouble(data + vstep * 2);
            npyv_longdouble c2 = npyv_loada_longdouble(data_out + vstep * 2);
            
#line 312
            npyv_longdouble b3 = npyv_loada_longdouble(data + vstep * 3);
            npyv_longdouble c3 = npyv_loada_longdouble(data_out + vstep * 3);
            
            #line 318
            npyv_longdouble abc0 = npyv_muladd_longdouble(v_scalar, b0, c0);
            
#line 318
            npyv_longdouble abc1 = npyv_muladd_longdouble(v_scalar, b1, c1);
            
#line 318
            npyv_longdouble abc2 = npyv_muladd_longdouble(v_scalar, b2, c2);
            
#line 318
            npyv_longdouble abc3 = npyv_muladd_longdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_longdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_longdouble b0 = npyv_load_longdouble(data + vstep * 0);
            npyv_longdouble c0 = npyv_load_longdouble(data_out + vstep * 0);
            
#line 312
            npyv_longdouble b1 = npyv_load_longdouble(data + vstep * 1);
            npyv_longdouble c1 = npyv_load_longdouble(data_out + vstep * 1);
            
#line 312
            npyv_longdouble b2 = npyv_load_longdouble(data + vstep * 2);
            npyv_longdouble c2 = npyv_load_longdouble(data_out + vstep * 2);
            
#line 312
            npyv_longdouble b3 = npyv_load_longdouble(data + vstep * 3);
            npyv_longdouble c3 = npyv_load_longdouble(data_out + vstep * 3);
            
            #line 318
            npyv_longdouble abc0 = npyv_muladd_longdouble(v_scalar, b0, c0);
            
#line 318
            npyv_longdouble abc1 = npyv_muladd_longdouble(v_scalar, b1, c1);
            
#line 318
            npyv_longdouble abc2 = npyv_muladd_longdouble(v_scalar, b2, c2);
            
#line 318
            npyv_longdouble abc3 = npyv_muladd_longdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_store_longdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data_out, count);
        npyv_store_till_longdouble(data_out, count, npyv_muladd_longdouble(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longdouble b0 = (data[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 340
        const npy_longdouble b1 = (data[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 340
        const npy_longdouble b2 = (data[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 340
        const npy_longdouble b3 = (data[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 346
        const npy_longdouble abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longdouble abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longdouble abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longdouble abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longdouble b = (*data);
        const npy_longdouble c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_longdouble
}

static void
longdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_longdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_longdouble;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_longdouble a0 = npyv_loada_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_loada_longdouble(data1 + vstep * 0);
            npyv_longdouble c0 = npyv_loada_longdouble(data_out + vstep * 0);
            
#line 390
            npyv_longdouble a1 = npyv_loada_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_loada_longdouble(data1 + vstep * 1);
            npyv_longdouble c1 = npyv_loada_longdouble(data_out + vstep * 1);
            
#line 390
            npyv_longdouble a2 = npyv_loada_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_loada_longdouble(data1 + vstep * 2);
            npyv_longdouble c2 = npyv_loada_longdouble(data_out + vstep * 2);
            
#line 390
            npyv_longdouble a3 = npyv_loada_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_loada_longdouble(data1 + vstep * 3);
            npyv_longdouble c3 = npyv_loada_longdouble(data_out + vstep * 3);
            
            #line 397
            npyv_longdouble abc0 = npyv_muladd_longdouble(a0, b0, c0);
            
#line 397
            npyv_longdouble abc1 = npyv_muladd_longdouble(a1, b1, c1);
            
#line 397
            npyv_longdouble abc2 = npyv_muladd_longdouble(a2, b2, c2);
            
#line 397
            npyv_longdouble abc3 = npyv_muladd_longdouble(a3, b3, c3);
            
            #line 402
            npyv_storea_longdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_longdouble a0 = npyv_load_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_load_longdouble(data1 + vstep * 0);
            npyv_longdouble c0 = npyv_load_longdouble(data_out + vstep * 0);
            
#line 390
            npyv_longdouble a1 = npyv_load_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_load_longdouble(data1 + vstep * 1);
            npyv_longdouble c1 = npyv_load_longdouble(data_out + vstep * 1);
            
#line 390
            npyv_longdouble a2 = npyv_load_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_load_longdouble(data1 + vstep * 2);
            npyv_longdouble c2 = npyv_load_longdouble(data_out + vstep * 2);
            
#line 390
            npyv_longdouble a3 = npyv_load_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_load_longdouble(data1 + vstep * 3);
            npyv_longdouble c3 = npyv_load_longdouble(data_out + vstep * 3);
            
            #line 397
            npyv_longdouble abc0 = npyv_muladd_longdouble(a0, b0, c0);
            
#line 397
            npyv_longdouble abc1 = npyv_muladd_longdouble(a1, b1, c1);
            
#line 397
            npyv_longdouble abc2 = npyv_muladd_longdouble(a2, b2, c2);
            
#line 397
            npyv_longdouble abc3 = npyv_muladd_longdouble(a3, b3, c3);
            
            #line 402
            npyv_store_longdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_longdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data0, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data1, count);
        npyv_longdouble c = npyv_load_tillz_longdouble(data_out, count);
        npyv_store_till_longdouble(data_out, count, npyv_muladd_longdouble(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longdouble a0 = (data0[0]);
        const npy_longdouble b0 = (data1[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 420
        const npy_longdouble a1 = (data0[1]);
        const npy_longdouble b1 = (data1[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 420
        const npy_longdouble a2 = (data0[2]);
        const npy_longdouble b2 = (data1[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 420
        const npy_longdouble a3 = (data0[3]);
        const npy_longdouble b3 = (data1[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 427
        const npy_longdouble abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longdouble abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longdouble abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longdouble abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        const npy_longdouble c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_longdouble

}

/* Some extra specializations for the two operand case */
static void
longdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value0 = (*(npy_longdouble *)dataptr[0]);
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    longdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
longdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value1 = (*(npy_longdouble *)dataptr[1]);
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    longdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble accum = 0;

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_longdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_longdouble;
    npyv_longdouble v_accum = npyv_zero_longdouble();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_longdouble a0 = npyv_loada_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_loada_longdouble(data1 + vstep * 0);
            
#line 501
            npyv_longdouble a1 = npyv_loada_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_loada_longdouble(data1 + vstep * 1);
            
#line 501
            npyv_longdouble a2 = npyv_loada_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_loada_longdouble(data1 + vstep * 2);
            
#line 501
            npyv_longdouble a3 = npyv_loada_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_loada_longdouble(data1 + vstep * 3);
            
            npyv_longdouble ab3 = npyv_muladd_longdouble(a3, b3, v_accum);
            npyv_longdouble ab2 = npyv_muladd_longdouble(a2, b2, ab3);
            npyv_longdouble ab1 = npyv_muladd_longdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_longdouble(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_longdouble a0 = npyv_load_longdouble(data0 + vstep * 0);
            npyv_longdouble b0 = npyv_load_longdouble(data1 + vstep * 0);
            
#line 501
            npyv_longdouble a1 = npyv_load_longdouble(data0 + vstep * 1);
            npyv_longdouble b1 = npyv_load_longdouble(data1 + vstep * 1);
            
#line 501
            npyv_longdouble a2 = npyv_load_longdouble(data0 + vstep * 2);
            npyv_longdouble b2 = npyv_load_longdouble(data1 + vstep * 2);
            
#line 501
            npyv_longdouble a3 = npyv_load_longdouble(data0 + vstep * 3);
            npyv_longdouble b3 = npyv_load_longdouble(data1 + vstep * 3);
            
            npyv_longdouble ab3 = npyv_muladd_longdouble(a3, b3, v_accum);
            npyv_longdouble ab2 = npyv_muladd_longdouble(a2, b2, ab3);
            npyv_longdouble ab1 = npyv_muladd_longdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_longdouble(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_longdouble a = npyv_load_tillz_longdouble(data0, count);
        npyv_longdouble b = npyv_load_tillz_longdouble(data1, count);
        v_accum = npyv_muladd_longdouble(a, b, v_accum);
    }
    accum = npyv_sum_longdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longdouble ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longdouble ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longdouble ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longdouble ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_longdouble
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble value0 = (*(npy_longdouble *)dataptr[0]);
    npy_longdouble accum = longdouble_sum_of_arr(data1, count);
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble value1 = (*(npy_longdouble *)dataptr[1]);
    npy_longdouble accum = longdouble_sum_of_arr(data0, count);
    *(npy_longdouble *)dataptr[2] = ((*(npy_longdouble *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !0

static void
longdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
    npy_longdouble *data1 = (npy_longdouble *)dataptr[1];
    npy_longdouble *data2 = (npy_longdouble *)dataptr[2];
    npy_longdouble *data_out = (npy_longdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
longdouble_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        *(npy_longdouble *)dataptr[nop] = (temp +
                                           (*(npy_longdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_longdouble);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_longdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
longdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !0
    npy_longdouble *data = (npy_longdouble *)dataptr[0];
    npy_longdouble accum = longdouble_sum_of_arr(data, count);
    *((npy_longdouble *)dataptr[1]) = (accum + (*((npy_longdouble *)dataptr[1])));
#else
    npy_longdouble accum_re = 0, accum_im = 0;
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longdouble re01 = data0[0] + data0[2];
        const npy_longdouble re23 = data0[4] + data0[6];
        const npy_longdouble im13 = data0[1] + data0[3];
        const npy_longdouble im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#endif // !0
}

#endif /* 1000 == 1 */

static void
longdouble_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 0
    npy_longdouble accum_re = 0, accum_im = 0;
#else
    npy_longdouble accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !0)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !0
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !0
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("longdouble_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !0
#  if 1000 == 1
        accum += (*(npy_longdouble *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_longdouble *)data0) *
                 (*(npy_longdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_longdouble *)data0) *
                 (*(npy_longdouble *)data1) *
                 (*(npy_longdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longdouble temp = (*(npy_longdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_longdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_longdouble *)data0)[0];
        accum_im += ((npy_longdouble *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 0
#  if 1000 <= 3
    ((npy_longdouble *)dataptr[1000])[0] += accum_re;
    ((npy_longdouble *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_longdouble *)dataptr[nop])[0] += accum_re;
    ((npy_longdouble *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_longdouble *)dataptr[1000]) = (accum +
                                    (*((npy_longdouble *)dataptr[1000])));
#  else
    *((npy_longdouble *)dataptr[nop]) = (accum +
                                    (*((npy_longdouble *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !1
static NPY_GCC_OPT_3 npy_float cfloat_sum_of_arr(npy_cfloat *data, npy_intp count)
{
    npy_float accum = 0;
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_f32 a0 = npyv_loada_f32(data + vstep * 0);
            
#line 96
            npyv_f32 a1 = npyv_loada_f32(data + vstep * 1);
            
#line 96
            npyv_f32 a2 = npyv_loada_f32(data + vstep * 2);
            
#line 96
            npyv_f32 a3 = npyv_loada_f32(data + vstep * 3);
            
            npyv_f32 a01   = npyv_add_f32(a0, a1);
            npyv_f32 a23   = npyv_add_f32(a2, a3);
            npyv_f32 a0123 = npyv_add_f32(a01, a23);
                     v_accum = npyv_add_f32(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_f32 a0 = npyv_load_f32(data + vstep * 0);
            
#line 96
            npyv_f32 a1 = npyv_load_f32(data + vstep * 1);
            
#line 96
            npyv_f32 a2 = npyv_load_f32(data + vstep * 2);
            
#line 96
            npyv_f32 a3 = npyv_load_f32(data + vstep * 3);
            
            npyv_f32 a01   = npyv_add_f32(a0, a1);
            npyv_f32 a23   = npyv_add_f32(a2, a3);
            npyv_f32 a0123 = npyv_add_f32(a01, a23);
                     v_accum = npyv_add_f32(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        v_accum = npyv_add_f32(a, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_float a01 = (*data) + (data[1]);
        const npy_float a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_cfloat
    return accum;
}
#endif

#line 131
static void
cfloat_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !1)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 1 == 1
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) *
                                         (*(npy_cfloat *)data1) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) *
                                         (*(npy_cfloat *)data1) *
                                         (*(npy_cfloat *)data2) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        *(npy_cfloat *)dataptr[nop] = (temp +
                                           (*(npy_cfloat *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
cfloat_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
cfloat_sum_of_products_muladd(npy_cfloat *data, npy_cfloat *data_out, npy_float scalar, npy_intp count)
{
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;
    const npyv_f32 v_scalar = npyv_setall_f32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_loada_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_loada_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_loada_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_loada_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_load_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_load_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_load_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_load_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        npyv_f32 b = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = (data[0]);
        const npy_float c0 = (data_out[0]);
        
#line 340
        const npy_float b1 = (data[1]);
        const npy_float c1 = (data_out[1]);
        
#line 340
        const npy_float b2 = (data[2]);
        const npy_float c2 = (data_out[2]);
        
#line 340
        const npy_float b3 = (data[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = (*data);
        const npy_float c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_cfloat
}

static void
cfloat_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_cfloat
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        npyv_f32 c = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = (data0[0]);
        const npy_float b0 = (data1[0]);
        const npy_float c0 = (data_out[0]);
        
#line 420
        const npy_float a1 = (data0[1]);
        const npy_float b1 = (data1[1]);
        const npy_float c1 = (data_out[1]);
        
#line 420
        const npy_float a2 = (data0[2]);
        const npy_float b2 = (data1[2]);
        const npy_float c2 = (data_out[2]);
        
#line 420
        const npy_float a3 = (data0[3]);
        const npy_float b3 = (data1[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        const npy_float c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_cfloat

}

/* Some extra specializations for the two operand case */
static void
cfloat_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = (*(npy_cfloat *)dataptr[0]);
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    cfloat_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
cfloat_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = (*(npy_cfloat *)dataptr[1]);
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    cfloat_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        v_accum = npyv_muladd_f32(a, b, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_float ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_float ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_float ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_cfloat
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_float value0 = (*(npy_cfloat *)dataptr[0]);
    npy_float accum = cfloat_sum_of_arr(data1, count);
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_float value1 = (*(npy_cfloat *)dataptr[1]);
    npy_float accum = cfloat_sum_of_arr(data0, count);
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !1

static void
cfloat_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data2 = (npy_cfloat *)dataptr[2];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
cfloat_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        *(npy_cfloat *)dataptr[nop] = (temp +
                                           (*(npy_cfloat *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_cfloat);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_cfloat);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_cfloat *data = (npy_cfloat *)dataptr[0];
    npy_float accum = cfloat_sum_of_arr(data, count);
    *((npy_cfloat *)dataptr[1]) = (accum + (*((npy_cfloat *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 1 == 1 */

static void
cfloat_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 1 == 1
        accum += (*(npy_cfloat *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_cfloat *)data0) *
                 (*(npy_cfloat *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_cfloat *)data0) *
                 (*(npy_cfloat *)data1) *
                 (*(npy_cfloat *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 1 <= 3
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_cfloat *)dataptr[1]) = (accum +
                                    (*((npy_cfloat *)dataptr[1])));
#  else
    *((npy_cfloat *)dataptr[nop]) = (accum +
                                    (*((npy_cfloat *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
cfloat_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !1)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 2 == 1
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) *
                                         (*(npy_cfloat *)data1) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) *
                                         (*(npy_cfloat *)data1) *
                                         (*(npy_cfloat *)data2) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        *(npy_cfloat *)dataptr[nop] = (temp +
                                           (*(npy_cfloat *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
cfloat_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
cfloat_sum_of_products_muladd(npy_cfloat *data, npy_cfloat *data_out, npy_float scalar, npy_intp count)
{
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;
    const npyv_f32 v_scalar = npyv_setall_f32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_loada_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_loada_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_loada_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_loada_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_load_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_load_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_load_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_load_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        npyv_f32 b = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = (data[0]);
        const npy_float c0 = (data_out[0]);
        
#line 340
        const npy_float b1 = (data[1]);
        const npy_float c1 = (data_out[1]);
        
#line 340
        const npy_float b2 = (data[2]);
        const npy_float c2 = (data_out[2]);
        
#line 340
        const npy_float b3 = (data[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = (*data);
        const npy_float c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_cfloat
}

static void
cfloat_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_cfloat
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        npyv_f32 c = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = (data0[0]);
        const npy_float b0 = (data1[0]);
        const npy_float c0 = (data_out[0]);
        
#line 420
        const npy_float a1 = (data0[1]);
        const npy_float b1 = (data1[1]);
        const npy_float c1 = (data_out[1]);
        
#line 420
        const npy_float a2 = (data0[2]);
        const npy_float b2 = (data1[2]);
        const npy_float c2 = (data_out[2]);
        
#line 420
        const npy_float a3 = (data0[3]);
        const npy_float b3 = (data1[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        const npy_float c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_cfloat

}

/* Some extra specializations for the two operand case */
static void
cfloat_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = (*(npy_cfloat *)dataptr[0]);
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    cfloat_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
cfloat_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = (*(npy_cfloat *)dataptr[1]);
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    cfloat_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        v_accum = npyv_muladd_f32(a, b, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_float ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_float ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_float ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_cfloat
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_float value0 = (*(npy_cfloat *)dataptr[0]);
    npy_float accum = cfloat_sum_of_arr(data1, count);
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_float value1 = (*(npy_cfloat *)dataptr[1]);
    npy_float accum = cfloat_sum_of_arr(data0, count);
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !1

static void
cfloat_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data2 = (npy_cfloat *)dataptr[2];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
cfloat_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        *(npy_cfloat *)dataptr[nop] = (temp +
                                           (*(npy_cfloat *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_cfloat);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_cfloat);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_cfloat *data = (npy_cfloat *)dataptr[0];
    npy_float accum = cfloat_sum_of_arr(data, count);
    *((npy_cfloat *)dataptr[1]) = (accum + (*((npy_cfloat *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 2 == 1 */

static void
cfloat_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 2 == 1
        accum += (*(npy_cfloat *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_cfloat *)data0) *
                 (*(npy_cfloat *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_cfloat *)data0) *
                 (*(npy_cfloat *)data1) *
                 (*(npy_cfloat *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 2 <= 3
    ((npy_float *)dataptr[2])[0] += accum_re;
    ((npy_float *)dataptr[2])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_cfloat *)dataptr[2]) = (accum +
                                    (*((npy_cfloat *)dataptr[2])));
#  else
    *((npy_cfloat *)dataptr[nop]) = (accum +
                                    (*((npy_cfloat *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
cfloat_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !1)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 3 == 1
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) *
                                         (*(npy_cfloat *)data1) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) *
                                         (*(npy_cfloat *)data1) *
                                         (*(npy_cfloat *)data2) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        *(npy_cfloat *)dataptr[nop] = (temp +
                                           (*(npy_cfloat *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
cfloat_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
cfloat_sum_of_products_muladd(npy_cfloat *data, npy_cfloat *data_out, npy_float scalar, npy_intp count)
{
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;
    const npyv_f32 v_scalar = npyv_setall_f32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_loada_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_loada_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_loada_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_loada_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_load_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_load_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_load_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_load_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        npyv_f32 b = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = (data[0]);
        const npy_float c0 = (data_out[0]);
        
#line 340
        const npy_float b1 = (data[1]);
        const npy_float c1 = (data_out[1]);
        
#line 340
        const npy_float b2 = (data[2]);
        const npy_float c2 = (data_out[2]);
        
#line 340
        const npy_float b3 = (data[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = (*data);
        const npy_float c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_cfloat
}

static void
cfloat_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_cfloat
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        npyv_f32 c = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = (data0[0]);
        const npy_float b0 = (data1[0]);
        const npy_float c0 = (data_out[0]);
        
#line 420
        const npy_float a1 = (data0[1]);
        const npy_float b1 = (data1[1]);
        const npy_float c1 = (data_out[1]);
        
#line 420
        const npy_float a2 = (data0[2]);
        const npy_float b2 = (data1[2]);
        const npy_float c2 = (data_out[2]);
        
#line 420
        const npy_float a3 = (data0[3]);
        const npy_float b3 = (data1[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        const npy_float c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_cfloat

}

/* Some extra specializations for the two operand case */
static void
cfloat_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = (*(npy_cfloat *)dataptr[0]);
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    cfloat_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
cfloat_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = (*(npy_cfloat *)dataptr[1]);
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    cfloat_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        v_accum = npyv_muladd_f32(a, b, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_float ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_float ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_float ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_cfloat
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_float value0 = (*(npy_cfloat *)dataptr[0]);
    npy_float accum = cfloat_sum_of_arr(data1, count);
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_float value1 = (*(npy_cfloat *)dataptr[1]);
    npy_float accum = cfloat_sum_of_arr(data0, count);
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !1

static void
cfloat_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data2 = (npy_cfloat *)dataptr[2];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
cfloat_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        *(npy_cfloat *)dataptr[nop] = (temp +
                                           (*(npy_cfloat *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_cfloat);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_cfloat);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_cfloat *data = (npy_cfloat *)dataptr[0];
    npy_float accum = cfloat_sum_of_arr(data, count);
    *((npy_cfloat *)dataptr[1]) = (accum + (*((npy_cfloat *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 3 == 1 */

static void
cfloat_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 3 == 1
        accum += (*(npy_cfloat *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_cfloat *)data0) *
                 (*(npy_cfloat *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_cfloat *)data0) *
                 (*(npy_cfloat *)data1) *
                 (*(npy_cfloat *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 3 <= 3
    ((npy_float *)dataptr[3])[0] += accum_re;
    ((npy_float *)dataptr[3])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_cfloat *)dataptr[3]) = (accum +
                                    (*((npy_cfloat *)dataptr[3])));
#  else
    *((npy_cfloat *)dataptr[nop]) = (accum +
                                    (*((npy_cfloat *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
cfloat_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !1)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 1000 == 1
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) *
                                         (*(npy_cfloat *)data1) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_cfloat *)data_out = ((*(npy_cfloat *)data0) *
                                         (*(npy_cfloat *)data1) *
                                         (*(npy_cfloat *)data2) +
                                         (*(npy_cfloat *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        *(npy_cfloat *)dataptr[nop] = (temp +
                                           (*(npy_cfloat *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_float *)data_out)[0] = ((npy_float *)data0)[0] +
                                         ((npy_float *)data_out)[0];
        ((npy_float *)data_out)[1] = ((npy_float *)data0)[1] +
                                         ((npy_float *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
cfloat_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_float *)data_out + 2*6)[0] =
                                    ((npy_float *)data0 + 2*6)[0] +
                                    ((npy_float *)data_out + 2*6)[0];
            ((npy_float *)data_out + 2*6)[1] =
                                    ((npy_float *)data0 + 2*6)[1] +
                                    ((npy_float *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_float *)data_out + 2*5)[0] =
                                    ((npy_float *)data0 + 2*5)[0] +
                                    ((npy_float *)data_out + 2*5)[0];
            ((npy_float *)data_out + 2*5)[1] =
                                    ((npy_float *)data0 + 2*5)[1] +
                                    ((npy_float *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_float *)data_out + 2*4)[0] =
                                    ((npy_float *)data0 + 2*4)[0] +
                                    ((npy_float *)data_out + 2*4)[0];
            ((npy_float *)data_out + 2*4)[1] =
                                    ((npy_float *)data0 + 2*4)[1] +
                                    ((npy_float *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_float *)data_out + 2*3)[0] =
                                    ((npy_float *)data0 + 2*3)[0] +
                                    ((npy_float *)data_out + 2*3)[0];
            ((npy_float *)data_out + 2*3)[1] =
                                    ((npy_float *)data0 + 2*3)[1] +
                                    ((npy_float *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_float *)data_out + 2*2)[0] =
                                    ((npy_float *)data0 + 2*2)[0] +
                                    ((npy_float *)data_out + 2*2)[0];
            ((npy_float *)data_out + 2*2)[1] =
                                    ((npy_float *)data0 + 2*2)[1] +
                                    ((npy_float *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_float *)data_out + 2*1)[0] =
                                    ((npy_float *)data0 + 2*1)[0] +
                                    ((npy_float *)data_out + 2*1)[0];
            ((npy_float *)data_out + 2*1)[1] =
                                    ((npy_float *)data0 + 2*1)[1] +
                                    ((npy_float *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_float *)data_out + 2*0)[0] =
                                    ((npy_float *)data0 + 2*0)[0] +
                                    ((npy_float *)data_out + 2*0)[0];
            ((npy_float *)data_out + 2*0)[1] =
                                    ((npy_float *)data0 + 2*0)[1] +
                                    ((npy_float *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_float *)data_out + 2*0)[0] =
                                ((npy_float *)data0 + 2*0)[0] +
                                ((npy_float *)data_out + 2*0)[0];
        ((npy_float *)data_out + 2*0)[1] =
                                ((npy_float *)data0 + 2*0)[1] +
                                ((npy_float *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_float *)data_out + 2*1)[0] =
                                ((npy_float *)data0 + 2*1)[0] +
                                ((npy_float *)data_out + 2*1)[0];
        ((npy_float *)data_out + 2*1)[1] =
                                ((npy_float *)data0 + 2*1)[1] +
                                ((npy_float *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_float *)data_out + 2*2)[0] =
                                ((npy_float *)data0 + 2*2)[0] +
                                ((npy_float *)data_out + 2*2)[0];
        ((npy_float *)data_out + 2*2)[1] =
                                ((npy_float *)data0 + 2*2)[1] +
                                ((npy_float *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_float *)data_out + 2*3)[0] =
                                ((npy_float *)data0 + 2*3)[0] +
                                ((npy_float *)data_out + 2*3)[0];
        ((npy_float *)data_out + 2*3)[1] =
                                ((npy_float *)data0 + 2*3)[1] +
                                ((npy_float *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_float *)data_out + 2*4)[0] =
                                ((npy_float *)data0 + 2*4)[0] +
                                ((npy_float *)data_out + 2*4)[0];
        ((npy_float *)data_out + 2*4)[1] =
                                ((npy_float *)data0 + 2*4)[1] +
                                ((npy_float *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_float *)data_out + 2*5)[0] =
                                ((npy_float *)data0 + 2*5)[0] +
                                ((npy_float *)data_out + 2*5)[0];
        ((npy_float *)data_out + 2*5)[1] =
                                ((npy_float *)data0 + 2*5)[1] +
                                ((npy_float *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_float *)data_out + 2*6)[0] =
                                ((npy_float *)data0 + 2*6)[0] +
                                ((npy_float *)data_out + 2*6)[0];
        ((npy_float *)data_out + 2*6)[1] =
                                ((npy_float *)data0 + 2*6)[1] +
                                ((npy_float *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_float *)data_out + 2*7)[0] =
                                ((npy_float *)data0 + 2*7)[0] +
                                ((npy_float *)data_out + 2*7)[0];
        ((npy_float *)data_out + 2*7)[1] =
                                ((npy_float *)data0 + 2*7)[1] +
                                ((npy_float *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
cfloat_sum_of_products_muladd(npy_cfloat *data, npy_cfloat *data_out, npy_float scalar, npy_intp count)
{
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;
    const npyv_f32 v_scalar = npyv_setall_f32(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_loada_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_loada_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_loada_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_loada_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f32 b0 = npyv_load_f32(data + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 312
            npyv_f32 b1 = npyv_load_f32(data + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 312
            npyv_f32 b2 = npyv_load_f32(data + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 312
            npyv_f32 b3 = npyv_load_f32(data + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 318
            npyv_f32 abc0 = npyv_muladd_f32(v_scalar, b0, c0);
            
#line 318
            npyv_f32 abc1 = npyv_muladd_f32(v_scalar, b1, c1);
            
#line 318
            npyv_f32 abc2 = npyv_muladd_f32(v_scalar, b2, c2);
            
#line 318
            npyv_f32 abc3 = npyv_muladd_f32(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data, count);
        npyv_f32 b = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_float b0 = (data[0]);
        const npy_float c0 = (data_out[0]);
        
#line 340
        const npy_float b1 = (data[1]);
        const npy_float c1 = (data_out[1]);
        
#line 340
        const npy_float b2 = (data[2]);
        const npy_float c2 = (data_out[2]);
        
#line 340
        const npy_float b3 = (data[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 346
        const npy_float abc0 = scalar * b0 + c0;
        
#line 346
        const npy_float abc1 = scalar * b1 + c1;
        
#line 346
        const npy_float abc2 = scalar * b2 + c2;
        
#line 346
        const npy_float abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_float b = (*data);
        const npy_float c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_cfloat
}

static void
cfloat_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_cfloat
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f32;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_loada_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_loada_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_loada_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_loada_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_storea_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            npyv_f32 c0 = npyv_load_f32(data_out + vstep * 0);
            
#line 390
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            npyv_f32 c1 = npyv_load_f32(data_out + vstep * 1);
            
#line 390
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            npyv_f32 c2 = npyv_load_f32(data_out + vstep * 2);
            
#line 390
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            npyv_f32 c3 = npyv_load_f32(data_out + vstep * 3);
            
            #line 397
            npyv_f32 abc0 = npyv_muladd_f32(a0, b0, c0);
            
#line 397
            npyv_f32 abc1 = npyv_muladd_f32(a1, b1, c1);
            
#line 397
            npyv_f32 abc2 = npyv_muladd_f32(a2, b2, c2);
            
#line 397
            npyv_f32 abc3 = npyv_muladd_f32(a3, b3, c3);
            
            #line 402
            npyv_store_f32(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f32(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f32(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f32(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        npyv_f32 c = npyv_load_tillz_f32(data_out, count);
        npyv_store_till_f32(data_out, count, npyv_muladd_f32(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_float a0 = (data0[0]);
        const npy_float b0 = (data1[0]);
        const npy_float c0 = (data_out[0]);
        
#line 420
        const npy_float a1 = (data0[1]);
        const npy_float b1 = (data1[1]);
        const npy_float c1 = (data_out[1]);
        
#line 420
        const npy_float a2 = (data0[2]);
        const npy_float b2 = (data1[2]);
        const npy_float c2 = (data_out[2]);
        
#line 420
        const npy_float a3 = (data0[3]);
        const npy_float b3 = (data1[3]);
        const npy_float c3 = (data_out[3]);
        
        #line 427
        const npy_float abc0 = a0 * b0 + c0;
        
#line 427
        const npy_float abc1 = a1 * b1 + c1;
        
#line 427
        const npy_float abc2 = a2 * b2 + c2;
        
#line 427
        const npy_float abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        const npy_float c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_cfloat

}

/* Some extra specializations for the two operand case */
static void
cfloat_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value0 = (*(npy_cfloat *)dataptr[0]);
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    cfloat_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
cfloat_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_float value1 = (*(npy_cfloat *)dataptr[1]);
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    cfloat_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_float accum = 0;

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_cfloat
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f32;
    npyv_f32 v_accum = npyv_zero_f32();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_loada_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_loada_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_loada_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_loada_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_loada_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_loada_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_loada_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_loada_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f32 a0 = npyv_load_f32(data0 + vstep * 0);
            npyv_f32 b0 = npyv_load_f32(data1 + vstep * 0);
            
#line 501
            npyv_f32 a1 = npyv_load_f32(data0 + vstep * 1);
            npyv_f32 b1 = npyv_load_f32(data1 + vstep * 1);
            
#line 501
            npyv_f32 a2 = npyv_load_f32(data0 + vstep * 2);
            npyv_f32 b2 = npyv_load_f32(data1 + vstep * 2);
            
#line 501
            npyv_f32 a3 = npyv_load_f32(data0 + vstep * 3);
            npyv_f32 b3 = npyv_load_f32(data1 + vstep * 3);
            
            npyv_f32 ab3 = npyv_muladd_f32(a3, b3, v_accum);
            npyv_f32 ab2 = npyv_muladd_f32(a2, b2, ab3);
            npyv_f32 ab1 = npyv_muladd_f32(a1, b1, ab2);
                   v_accum = npyv_muladd_f32(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f32 a = npyv_load_tillz_f32(data0, count);
        npyv_f32 b = npyv_load_tillz_f32(data1, count);
        v_accum = npyv_muladd_f32(a, b, v_accum);
    }
    accum = npyv_sum_f32(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_float ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_float ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_float ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_float ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_float a = (*data0);
        const npy_float b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_cfloat
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_float value0 = (*(npy_cfloat *)dataptr[0]);
    npy_float accum = cfloat_sum_of_arr(data1, count);
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_float value1 = (*(npy_cfloat *)dataptr[1]);
    npy_float accum = cfloat_sum_of_arr(data0, count);
    *(npy_cfloat *)dataptr[2] = ((*(npy_cfloat *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !1

static void
cfloat_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cfloat *data0 = (npy_cfloat *)dataptr[0];
    npy_cfloat *data1 = (npy_cfloat *)dataptr[1];
    npy_cfloat *data2 = (npy_cfloat *)dataptr[2];
    npy_cfloat *data_out = (npy_cfloat *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
cfloat_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        *(npy_cfloat *)dataptr[nop] = (temp +
                                           (*(npy_cfloat *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_cfloat);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_float *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[0];
        ((npy_float *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_float *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_cfloat);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
cfloat_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_cfloat *data = (npy_cfloat *)dataptr[0];
    npy_float accum = cfloat_sum_of_arr(data, count);
    *((npy_cfloat *)dataptr[1]) = (accum + (*((npy_cfloat *)dataptr[1])));
#else
    npy_float accum_re = 0, accum_im = 0;
    npy_float *data0 = (npy_float *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_float re01 = data0[0] + data0[2];
        const npy_float re23 = data0[4] + data0[6];
        const npy_float im13 = data0[1] + data0[3];
        const npy_float im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_float *)dataptr[1])[0] += accum_re;
    ((npy_float *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 1000 == 1 */

static void
cfloat_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_float accum_re = 0, accum_im = 0;
#else
    npy_float accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cfloat_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 1000 == 1
        accum += (*(npy_cfloat *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_cfloat *)data0) *
                 (*(npy_cfloat *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_cfloat *)data0) *
                 (*(npy_cfloat *)data1) *
                 (*(npy_cfloat *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_float temp = (*(npy_cfloat *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cfloat *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_float *)data0)[0];
        accum_im += ((npy_float *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_float re, im, tmp;
        int i;
        re = ((npy_float *)dataptr[0])[0];
        im = ((npy_float *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_float *)dataptr[i])[0] -
                  im * ((npy_float *)dataptr[i])[1];
            im = re * ((npy_float *)dataptr[i])[1] +
                 im * ((npy_float *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 1000 <= 3
    ((npy_float *)dataptr[1000])[0] += accum_re;
    ((npy_float *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_float *)dataptr[nop])[0] += accum_re;
    ((npy_float *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_cfloat *)dataptr[1000]) = (accum +
                                    (*((npy_cfloat *)dataptr[1000])));
#  else
    *((npy_cfloat *)dataptr[nop]) = (accum +
                                    (*((npy_cfloat *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !1
static NPY_GCC_OPT_3 npy_double cdouble_sum_of_arr(npy_cdouble *data, npy_intp count)
{
    npy_double accum = 0;
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_f64 a0 = npyv_loada_f64(data + vstep * 0);
            
#line 96
            npyv_f64 a1 = npyv_loada_f64(data + vstep * 1);
            
#line 96
            npyv_f64 a2 = npyv_loada_f64(data + vstep * 2);
            
#line 96
            npyv_f64 a3 = npyv_loada_f64(data + vstep * 3);
            
            npyv_f64 a01   = npyv_add_f64(a0, a1);
            npyv_f64 a23   = npyv_add_f64(a2, a3);
            npyv_f64 a0123 = npyv_add_f64(a01, a23);
                     v_accum = npyv_add_f64(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_f64 a0 = npyv_load_f64(data + vstep * 0);
            
#line 96
            npyv_f64 a1 = npyv_load_f64(data + vstep * 1);
            
#line 96
            npyv_f64 a2 = npyv_load_f64(data + vstep * 2);
            
#line 96
            npyv_f64 a3 = npyv_load_f64(data + vstep * 3);
            
            npyv_f64 a01   = npyv_add_f64(a0, a1);
            npyv_f64 a23   = npyv_add_f64(a2, a3);
            npyv_f64 a0123 = npyv_add_f64(a01, a23);
                     v_accum = npyv_add_f64(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        v_accum = npyv_add_f64(a, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_double a01 = (*data) + (data[1]);
        const npy_double a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_cdouble
    return accum;
}
#endif

#line 131
static void
cdouble_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !1)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 1 == 1
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) *
                                         (*(npy_cdouble *)data1) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) *
                                         (*(npy_cdouble *)data1) *
                                         (*(npy_cdouble *)data2) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        *(npy_cdouble *)dataptr[nop] = (temp +
                                           (*(npy_cdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_double *)data_out)[0] = ((npy_double *)data0)[0] +
                                         ((npy_double *)data_out)[0];
        ((npy_double *)data_out)[1] = ((npy_double *)data0)[1] +
                                         ((npy_double *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
cdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_double *)data_out + 2*6)[0] =
                                    ((npy_double *)data0 + 2*6)[0] +
                                    ((npy_double *)data_out + 2*6)[0];
            ((npy_double *)data_out + 2*6)[1] =
                                    ((npy_double *)data0 + 2*6)[1] +
                                    ((npy_double *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_double *)data_out + 2*5)[0] =
                                    ((npy_double *)data0 + 2*5)[0] +
                                    ((npy_double *)data_out + 2*5)[0];
            ((npy_double *)data_out + 2*5)[1] =
                                    ((npy_double *)data0 + 2*5)[1] +
                                    ((npy_double *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_double *)data_out + 2*4)[0] =
                                    ((npy_double *)data0 + 2*4)[0] +
                                    ((npy_double *)data_out + 2*4)[0];
            ((npy_double *)data_out + 2*4)[1] =
                                    ((npy_double *)data0 + 2*4)[1] +
                                    ((npy_double *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_double *)data_out + 2*3)[0] =
                                    ((npy_double *)data0 + 2*3)[0] +
                                    ((npy_double *)data_out + 2*3)[0];
            ((npy_double *)data_out + 2*3)[1] =
                                    ((npy_double *)data0 + 2*3)[1] +
                                    ((npy_double *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_double *)data_out + 2*2)[0] =
                                    ((npy_double *)data0 + 2*2)[0] +
                                    ((npy_double *)data_out + 2*2)[0];
            ((npy_double *)data_out + 2*2)[1] =
                                    ((npy_double *)data0 + 2*2)[1] +
                                    ((npy_double *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_double *)data_out + 2*1)[0] =
                                    ((npy_double *)data0 + 2*1)[0] +
                                    ((npy_double *)data_out + 2*1)[0];
            ((npy_double *)data_out + 2*1)[1] =
                                    ((npy_double *)data0 + 2*1)[1] +
                                    ((npy_double *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_double *)data_out + 2*0)[0] =
                                    ((npy_double *)data0 + 2*0)[0] +
                                    ((npy_double *)data_out + 2*0)[0];
            ((npy_double *)data_out + 2*0)[1] =
                                    ((npy_double *)data0 + 2*0)[1] +
                                    ((npy_double *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_double *)data_out + 2*0)[0] =
                                ((npy_double *)data0 + 2*0)[0] +
                                ((npy_double *)data_out + 2*0)[0];
        ((npy_double *)data_out + 2*0)[1] =
                                ((npy_double *)data0 + 2*0)[1] +
                                ((npy_double *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_double *)data_out + 2*1)[0] =
                                ((npy_double *)data0 + 2*1)[0] +
                                ((npy_double *)data_out + 2*1)[0];
        ((npy_double *)data_out + 2*1)[1] =
                                ((npy_double *)data0 + 2*1)[1] +
                                ((npy_double *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_double *)data_out + 2*2)[0] =
                                ((npy_double *)data0 + 2*2)[0] +
                                ((npy_double *)data_out + 2*2)[0];
        ((npy_double *)data_out + 2*2)[1] =
                                ((npy_double *)data0 + 2*2)[1] +
                                ((npy_double *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_double *)data_out + 2*3)[0] =
                                ((npy_double *)data0 + 2*3)[0] +
                                ((npy_double *)data_out + 2*3)[0];
        ((npy_double *)data_out + 2*3)[1] =
                                ((npy_double *)data0 + 2*3)[1] +
                                ((npy_double *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_double *)data_out + 2*4)[0] =
                                ((npy_double *)data0 + 2*4)[0] +
                                ((npy_double *)data_out + 2*4)[0];
        ((npy_double *)data_out + 2*4)[1] =
                                ((npy_double *)data0 + 2*4)[1] +
                                ((npy_double *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_double *)data_out + 2*5)[0] =
                                ((npy_double *)data0 + 2*5)[0] +
                                ((npy_double *)data_out + 2*5)[0];
        ((npy_double *)data_out + 2*5)[1] =
                                ((npy_double *)data0 + 2*5)[1] +
                                ((npy_double *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_double *)data_out + 2*6)[0] =
                                ((npy_double *)data0 + 2*6)[0] +
                                ((npy_double *)data_out + 2*6)[0];
        ((npy_double *)data_out + 2*6)[1] =
                                ((npy_double *)data0 + 2*6)[1] +
                                ((npy_double *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_double *)data_out + 2*7)[0] =
                                ((npy_double *)data0 + 2*7)[0] +
                                ((npy_double *)data_out + 2*7)[0];
        ((npy_double *)data_out + 2*7)[1] =
                                ((npy_double *)data0 + 2*7)[1] +
                                ((npy_double *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
cdouble_sum_of_products_muladd(npy_cdouble *data, npy_cdouble *data_out, npy_double scalar, npy_intp count)
{
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;
    const npyv_f64 v_scalar = npyv_setall_f64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_loada_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_loada_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_loada_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_loada_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_load_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_load_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_load_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_load_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        npyv_f64 b = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_double b0 = (data[0]);
        const npy_double c0 = (data_out[0]);
        
#line 340
        const npy_double b1 = (data[1]);
        const npy_double c1 = (data_out[1]);
        
#line 340
        const npy_double b2 = (data[2]);
        const npy_double c2 = (data_out[2]);
        
#line 340
        const npy_double b3 = (data[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 346
        const npy_double abc0 = scalar * b0 + c0;
        
#line 346
        const npy_double abc1 = scalar * b1 + c1;
        
#line 346
        const npy_double abc2 = scalar * b2 + c2;
        
#line 346
        const npy_double abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_double b = (*data);
        const npy_double c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_cdouble
}

static void
cdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_cdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        npyv_f64 c = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_double a0 = (data0[0]);
        const npy_double b0 = (data1[0]);
        const npy_double c0 = (data_out[0]);
        
#line 420
        const npy_double a1 = (data0[1]);
        const npy_double b1 = (data1[1]);
        const npy_double c1 = (data_out[1]);
        
#line 420
        const npy_double a2 = (data0[2]);
        const npy_double b2 = (data1[2]);
        const npy_double c2 = (data_out[2]);
        
#line 420
        const npy_double a3 = (data0[3]);
        const npy_double b3 = (data1[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 427
        const npy_double abc0 = a0 * b0 + c0;
        
#line 427
        const npy_double abc1 = a1 * b1 + c1;
        
#line 427
        const npy_double abc2 = a2 * b2 + c2;
        
#line 427
        const npy_double abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        const npy_double c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_cdouble

}

/* Some extra specializations for the two operand case */
static void
cdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value0 = (*(npy_cdouble *)dataptr[0]);
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    cdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
cdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value1 = (*(npy_cdouble *)dataptr[1]);
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    cdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_double accum = 0;

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        v_accum = npyv_muladd_f64(a, b, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_double ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_double ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_double ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_double ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_cdouble
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_double value0 = (*(npy_cdouble *)dataptr[0]);
    npy_double accum = cdouble_sum_of_arr(data1, count);
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_double value1 = (*(npy_cdouble *)dataptr[1]);
    npy_double accum = cdouble_sum_of_arr(data0, count);
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !1

static void
cdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data2 = (npy_cdouble *)dataptr[2];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
cdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        *(npy_cdouble *)dataptr[nop] = (temp +
                                           (*(npy_cdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_cdouble);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_cdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_cdouble *data = (npy_cdouble *)dataptr[0];
    npy_double accum = cdouble_sum_of_arr(data, count);
    *((npy_cdouble *)dataptr[1]) = (accum + (*((npy_cdouble *)dataptr[1])));
#else
    npy_double accum_re = 0, accum_im = 0;
    npy_double *data0 = (npy_double *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_double re01 = data0[0] + data0[2];
        const npy_double re23 = data0[4] + data0[6];
        const npy_double im13 = data0[1] + data0[3];
        const npy_double im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 1 == 1 */

static void
cdouble_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_double accum_re = 0, accum_im = 0;
#else
    npy_double accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 1 == 1
        accum += (*(npy_cdouble *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_cdouble *)data0) *
                 (*(npy_cdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_cdouble *)data0) *
                 (*(npy_cdouble *)data1) *
                 (*(npy_cdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_double *)data0)[0];
        accum_im += ((npy_double *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 1 <= 3
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#  else
    ((npy_double *)dataptr[nop])[0] += accum_re;
    ((npy_double *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_cdouble *)dataptr[1]) = (accum +
                                    (*((npy_cdouble *)dataptr[1])));
#  else
    *((npy_cdouble *)dataptr[nop]) = (accum +
                                    (*((npy_cdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
cdouble_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !1)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 2 == 1
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) *
                                         (*(npy_cdouble *)data1) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) *
                                         (*(npy_cdouble *)data1) *
                                         (*(npy_cdouble *)data2) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        *(npy_cdouble *)dataptr[nop] = (temp +
                                           (*(npy_cdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_double *)data_out)[0] = ((npy_double *)data0)[0] +
                                         ((npy_double *)data_out)[0];
        ((npy_double *)data_out)[1] = ((npy_double *)data0)[1] +
                                         ((npy_double *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
cdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_double *)data_out + 2*6)[0] =
                                    ((npy_double *)data0 + 2*6)[0] +
                                    ((npy_double *)data_out + 2*6)[0];
            ((npy_double *)data_out + 2*6)[1] =
                                    ((npy_double *)data0 + 2*6)[1] +
                                    ((npy_double *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_double *)data_out + 2*5)[0] =
                                    ((npy_double *)data0 + 2*5)[0] +
                                    ((npy_double *)data_out + 2*5)[0];
            ((npy_double *)data_out + 2*5)[1] =
                                    ((npy_double *)data0 + 2*5)[1] +
                                    ((npy_double *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_double *)data_out + 2*4)[0] =
                                    ((npy_double *)data0 + 2*4)[0] +
                                    ((npy_double *)data_out + 2*4)[0];
            ((npy_double *)data_out + 2*4)[1] =
                                    ((npy_double *)data0 + 2*4)[1] +
                                    ((npy_double *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_double *)data_out + 2*3)[0] =
                                    ((npy_double *)data0 + 2*3)[0] +
                                    ((npy_double *)data_out + 2*3)[0];
            ((npy_double *)data_out + 2*3)[1] =
                                    ((npy_double *)data0 + 2*3)[1] +
                                    ((npy_double *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_double *)data_out + 2*2)[0] =
                                    ((npy_double *)data0 + 2*2)[0] +
                                    ((npy_double *)data_out + 2*2)[0];
            ((npy_double *)data_out + 2*2)[1] =
                                    ((npy_double *)data0 + 2*2)[1] +
                                    ((npy_double *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_double *)data_out + 2*1)[0] =
                                    ((npy_double *)data0 + 2*1)[0] +
                                    ((npy_double *)data_out + 2*1)[0];
            ((npy_double *)data_out + 2*1)[1] =
                                    ((npy_double *)data0 + 2*1)[1] +
                                    ((npy_double *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_double *)data_out + 2*0)[0] =
                                    ((npy_double *)data0 + 2*0)[0] +
                                    ((npy_double *)data_out + 2*0)[0];
            ((npy_double *)data_out + 2*0)[1] =
                                    ((npy_double *)data0 + 2*0)[1] +
                                    ((npy_double *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_double *)data_out + 2*0)[0] =
                                ((npy_double *)data0 + 2*0)[0] +
                                ((npy_double *)data_out + 2*0)[0];
        ((npy_double *)data_out + 2*0)[1] =
                                ((npy_double *)data0 + 2*0)[1] +
                                ((npy_double *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_double *)data_out + 2*1)[0] =
                                ((npy_double *)data0 + 2*1)[0] +
                                ((npy_double *)data_out + 2*1)[0];
        ((npy_double *)data_out + 2*1)[1] =
                                ((npy_double *)data0 + 2*1)[1] +
                                ((npy_double *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_double *)data_out + 2*2)[0] =
                                ((npy_double *)data0 + 2*2)[0] +
                                ((npy_double *)data_out + 2*2)[0];
        ((npy_double *)data_out + 2*2)[1] =
                                ((npy_double *)data0 + 2*2)[1] +
                                ((npy_double *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_double *)data_out + 2*3)[0] =
                                ((npy_double *)data0 + 2*3)[0] +
                                ((npy_double *)data_out + 2*3)[0];
        ((npy_double *)data_out + 2*3)[1] =
                                ((npy_double *)data0 + 2*3)[1] +
                                ((npy_double *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_double *)data_out + 2*4)[0] =
                                ((npy_double *)data0 + 2*4)[0] +
                                ((npy_double *)data_out + 2*4)[0];
        ((npy_double *)data_out + 2*4)[1] =
                                ((npy_double *)data0 + 2*4)[1] +
                                ((npy_double *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_double *)data_out + 2*5)[0] =
                                ((npy_double *)data0 + 2*5)[0] +
                                ((npy_double *)data_out + 2*5)[0];
        ((npy_double *)data_out + 2*5)[1] =
                                ((npy_double *)data0 + 2*5)[1] +
                                ((npy_double *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_double *)data_out + 2*6)[0] =
                                ((npy_double *)data0 + 2*6)[0] +
                                ((npy_double *)data_out + 2*6)[0];
        ((npy_double *)data_out + 2*6)[1] =
                                ((npy_double *)data0 + 2*6)[1] +
                                ((npy_double *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_double *)data_out + 2*7)[0] =
                                ((npy_double *)data0 + 2*7)[0] +
                                ((npy_double *)data_out + 2*7)[0];
        ((npy_double *)data_out + 2*7)[1] =
                                ((npy_double *)data0 + 2*7)[1] +
                                ((npy_double *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
cdouble_sum_of_products_muladd(npy_cdouble *data, npy_cdouble *data_out, npy_double scalar, npy_intp count)
{
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;
    const npyv_f64 v_scalar = npyv_setall_f64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_loada_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_loada_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_loada_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_loada_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_load_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_load_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_load_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_load_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        npyv_f64 b = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_double b0 = (data[0]);
        const npy_double c0 = (data_out[0]);
        
#line 340
        const npy_double b1 = (data[1]);
        const npy_double c1 = (data_out[1]);
        
#line 340
        const npy_double b2 = (data[2]);
        const npy_double c2 = (data_out[2]);
        
#line 340
        const npy_double b3 = (data[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 346
        const npy_double abc0 = scalar * b0 + c0;
        
#line 346
        const npy_double abc1 = scalar * b1 + c1;
        
#line 346
        const npy_double abc2 = scalar * b2 + c2;
        
#line 346
        const npy_double abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_double b = (*data);
        const npy_double c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_cdouble
}

static void
cdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_cdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        npyv_f64 c = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_double a0 = (data0[0]);
        const npy_double b0 = (data1[0]);
        const npy_double c0 = (data_out[0]);
        
#line 420
        const npy_double a1 = (data0[1]);
        const npy_double b1 = (data1[1]);
        const npy_double c1 = (data_out[1]);
        
#line 420
        const npy_double a2 = (data0[2]);
        const npy_double b2 = (data1[2]);
        const npy_double c2 = (data_out[2]);
        
#line 420
        const npy_double a3 = (data0[3]);
        const npy_double b3 = (data1[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 427
        const npy_double abc0 = a0 * b0 + c0;
        
#line 427
        const npy_double abc1 = a1 * b1 + c1;
        
#line 427
        const npy_double abc2 = a2 * b2 + c2;
        
#line 427
        const npy_double abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        const npy_double c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_cdouble

}

/* Some extra specializations for the two operand case */
static void
cdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value0 = (*(npy_cdouble *)dataptr[0]);
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    cdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
cdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value1 = (*(npy_cdouble *)dataptr[1]);
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    cdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_double accum = 0;

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        v_accum = npyv_muladd_f64(a, b, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_double ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_double ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_double ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_double ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_cdouble
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_double value0 = (*(npy_cdouble *)dataptr[0]);
    npy_double accum = cdouble_sum_of_arr(data1, count);
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_double value1 = (*(npy_cdouble *)dataptr[1]);
    npy_double accum = cdouble_sum_of_arr(data0, count);
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !1

static void
cdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data2 = (npy_cdouble *)dataptr[2];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
cdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        *(npy_cdouble *)dataptr[nop] = (temp +
                                           (*(npy_cdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_cdouble);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_cdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_cdouble *data = (npy_cdouble *)dataptr[0];
    npy_double accum = cdouble_sum_of_arr(data, count);
    *((npy_cdouble *)dataptr[1]) = (accum + (*((npy_cdouble *)dataptr[1])));
#else
    npy_double accum_re = 0, accum_im = 0;
    npy_double *data0 = (npy_double *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_double re01 = data0[0] + data0[2];
        const npy_double re23 = data0[4] + data0[6];
        const npy_double im13 = data0[1] + data0[3];
        const npy_double im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 2 == 1 */

static void
cdouble_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_double accum_re = 0, accum_im = 0;
#else
    npy_double accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 2 == 1
        accum += (*(npy_cdouble *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_cdouble *)data0) *
                 (*(npy_cdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_cdouble *)data0) *
                 (*(npy_cdouble *)data1) *
                 (*(npy_cdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_double *)data0)[0];
        accum_im += ((npy_double *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 2 <= 3
    ((npy_double *)dataptr[2])[0] += accum_re;
    ((npy_double *)dataptr[2])[1] += accum_im;
#  else
    ((npy_double *)dataptr[nop])[0] += accum_re;
    ((npy_double *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_cdouble *)dataptr[2]) = (accum +
                                    (*((npy_cdouble *)dataptr[2])));
#  else
    *((npy_cdouble *)dataptr[nop]) = (accum +
                                    (*((npy_cdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
cdouble_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !1)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 3 == 1
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) *
                                         (*(npy_cdouble *)data1) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) *
                                         (*(npy_cdouble *)data1) *
                                         (*(npy_cdouble *)data2) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        *(npy_cdouble *)dataptr[nop] = (temp +
                                           (*(npy_cdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_double *)data_out)[0] = ((npy_double *)data0)[0] +
                                         ((npy_double *)data_out)[0];
        ((npy_double *)data_out)[1] = ((npy_double *)data0)[1] +
                                         ((npy_double *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
cdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_double *)data_out + 2*6)[0] =
                                    ((npy_double *)data0 + 2*6)[0] +
                                    ((npy_double *)data_out + 2*6)[0];
            ((npy_double *)data_out + 2*6)[1] =
                                    ((npy_double *)data0 + 2*6)[1] +
                                    ((npy_double *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_double *)data_out + 2*5)[0] =
                                    ((npy_double *)data0 + 2*5)[0] +
                                    ((npy_double *)data_out + 2*5)[0];
            ((npy_double *)data_out + 2*5)[1] =
                                    ((npy_double *)data0 + 2*5)[1] +
                                    ((npy_double *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_double *)data_out + 2*4)[0] =
                                    ((npy_double *)data0 + 2*4)[0] +
                                    ((npy_double *)data_out + 2*4)[0];
            ((npy_double *)data_out + 2*4)[1] =
                                    ((npy_double *)data0 + 2*4)[1] +
                                    ((npy_double *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_double *)data_out + 2*3)[0] =
                                    ((npy_double *)data0 + 2*3)[0] +
                                    ((npy_double *)data_out + 2*3)[0];
            ((npy_double *)data_out + 2*3)[1] =
                                    ((npy_double *)data0 + 2*3)[1] +
                                    ((npy_double *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_double *)data_out + 2*2)[0] =
                                    ((npy_double *)data0 + 2*2)[0] +
                                    ((npy_double *)data_out + 2*2)[0];
            ((npy_double *)data_out + 2*2)[1] =
                                    ((npy_double *)data0 + 2*2)[1] +
                                    ((npy_double *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_double *)data_out + 2*1)[0] =
                                    ((npy_double *)data0 + 2*1)[0] +
                                    ((npy_double *)data_out + 2*1)[0];
            ((npy_double *)data_out + 2*1)[1] =
                                    ((npy_double *)data0 + 2*1)[1] +
                                    ((npy_double *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_double *)data_out + 2*0)[0] =
                                    ((npy_double *)data0 + 2*0)[0] +
                                    ((npy_double *)data_out + 2*0)[0];
            ((npy_double *)data_out + 2*0)[1] =
                                    ((npy_double *)data0 + 2*0)[1] +
                                    ((npy_double *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_double *)data_out + 2*0)[0] =
                                ((npy_double *)data0 + 2*0)[0] +
                                ((npy_double *)data_out + 2*0)[0];
        ((npy_double *)data_out + 2*0)[1] =
                                ((npy_double *)data0 + 2*0)[1] +
                                ((npy_double *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_double *)data_out + 2*1)[0] =
                                ((npy_double *)data0 + 2*1)[0] +
                                ((npy_double *)data_out + 2*1)[0];
        ((npy_double *)data_out + 2*1)[1] =
                                ((npy_double *)data0 + 2*1)[1] +
                                ((npy_double *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_double *)data_out + 2*2)[0] =
                                ((npy_double *)data0 + 2*2)[0] +
                                ((npy_double *)data_out + 2*2)[0];
        ((npy_double *)data_out + 2*2)[1] =
                                ((npy_double *)data0 + 2*2)[1] +
                                ((npy_double *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_double *)data_out + 2*3)[0] =
                                ((npy_double *)data0 + 2*3)[0] +
                                ((npy_double *)data_out + 2*3)[0];
        ((npy_double *)data_out + 2*3)[1] =
                                ((npy_double *)data0 + 2*3)[1] +
                                ((npy_double *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_double *)data_out + 2*4)[0] =
                                ((npy_double *)data0 + 2*4)[0] +
                                ((npy_double *)data_out + 2*4)[0];
        ((npy_double *)data_out + 2*4)[1] =
                                ((npy_double *)data0 + 2*4)[1] +
                                ((npy_double *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_double *)data_out + 2*5)[0] =
                                ((npy_double *)data0 + 2*5)[0] +
                                ((npy_double *)data_out + 2*5)[0];
        ((npy_double *)data_out + 2*5)[1] =
                                ((npy_double *)data0 + 2*5)[1] +
                                ((npy_double *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_double *)data_out + 2*6)[0] =
                                ((npy_double *)data0 + 2*6)[0] +
                                ((npy_double *)data_out + 2*6)[0];
        ((npy_double *)data_out + 2*6)[1] =
                                ((npy_double *)data0 + 2*6)[1] +
                                ((npy_double *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_double *)data_out + 2*7)[0] =
                                ((npy_double *)data0 + 2*7)[0] +
                                ((npy_double *)data_out + 2*7)[0];
        ((npy_double *)data_out + 2*7)[1] =
                                ((npy_double *)data0 + 2*7)[1] +
                                ((npy_double *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
cdouble_sum_of_products_muladd(npy_cdouble *data, npy_cdouble *data_out, npy_double scalar, npy_intp count)
{
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;
    const npyv_f64 v_scalar = npyv_setall_f64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_loada_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_loada_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_loada_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_loada_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_load_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_load_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_load_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_load_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        npyv_f64 b = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_double b0 = (data[0]);
        const npy_double c0 = (data_out[0]);
        
#line 340
        const npy_double b1 = (data[1]);
        const npy_double c1 = (data_out[1]);
        
#line 340
        const npy_double b2 = (data[2]);
        const npy_double c2 = (data_out[2]);
        
#line 340
        const npy_double b3 = (data[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 346
        const npy_double abc0 = scalar * b0 + c0;
        
#line 346
        const npy_double abc1 = scalar * b1 + c1;
        
#line 346
        const npy_double abc2 = scalar * b2 + c2;
        
#line 346
        const npy_double abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_double b = (*data);
        const npy_double c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_cdouble
}

static void
cdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_cdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        npyv_f64 c = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_double a0 = (data0[0]);
        const npy_double b0 = (data1[0]);
        const npy_double c0 = (data_out[0]);
        
#line 420
        const npy_double a1 = (data0[1]);
        const npy_double b1 = (data1[1]);
        const npy_double c1 = (data_out[1]);
        
#line 420
        const npy_double a2 = (data0[2]);
        const npy_double b2 = (data1[2]);
        const npy_double c2 = (data_out[2]);
        
#line 420
        const npy_double a3 = (data0[3]);
        const npy_double b3 = (data1[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 427
        const npy_double abc0 = a0 * b0 + c0;
        
#line 427
        const npy_double abc1 = a1 * b1 + c1;
        
#line 427
        const npy_double abc2 = a2 * b2 + c2;
        
#line 427
        const npy_double abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        const npy_double c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_cdouble

}

/* Some extra specializations for the two operand case */
static void
cdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value0 = (*(npy_cdouble *)dataptr[0]);
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    cdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
cdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value1 = (*(npy_cdouble *)dataptr[1]);
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    cdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_double accum = 0;

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        v_accum = npyv_muladd_f64(a, b, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_double ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_double ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_double ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_double ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_cdouble
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_double value0 = (*(npy_cdouble *)dataptr[0]);
    npy_double accum = cdouble_sum_of_arr(data1, count);
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_double value1 = (*(npy_cdouble *)dataptr[1]);
    npy_double accum = cdouble_sum_of_arr(data0, count);
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !1

static void
cdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data2 = (npy_cdouble *)dataptr[2];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
cdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        *(npy_cdouble *)dataptr[nop] = (temp +
                                           (*(npy_cdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_cdouble);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_cdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_cdouble *data = (npy_cdouble *)dataptr[0];
    npy_double accum = cdouble_sum_of_arr(data, count);
    *((npy_cdouble *)dataptr[1]) = (accum + (*((npy_cdouble *)dataptr[1])));
#else
    npy_double accum_re = 0, accum_im = 0;
    npy_double *data0 = (npy_double *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_double re01 = data0[0] + data0[2];
        const npy_double re23 = data0[4] + data0[6];
        const npy_double im13 = data0[1] + data0[3];
        const npy_double im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 3 == 1 */

static void
cdouble_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_double accum_re = 0, accum_im = 0;
#else
    npy_double accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 3 == 1
        accum += (*(npy_cdouble *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_cdouble *)data0) *
                 (*(npy_cdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_cdouble *)data0) *
                 (*(npy_cdouble *)data1) *
                 (*(npy_cdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_double *)data0)[0];
        accum_im += ((npy_double *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 3 <= 3
    ((npy_double *)dataptr[3])[0] += accum_re;
    ((npy_double *)dataptr[3])[1] += accum_im;
#  else
    ((npy_double *)dataptr[nop])[0] += accum_re;
    ((npy_double *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_cdouble *)dataptr[3]) = (accum +
                                    (*((npy_cdouble *)dataptr[3])));
#  else
    *((npy_cdouble *)dataptr[nop]) = (accum +
                                    (*((npy_cdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
cdouble_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !1)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 1000 == 1
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) *
                                         (*(npy_cdouble *)data1) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_cdouble *)data_out = ((*(npy_cdouble *)data0) *
                                         (*(npy_cdouble *)data1) *
                                         (*(npy_cdouble *)data2) +
                                         (*(npy_cdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        *(npy_cdouble *)dataptr[nop] = (temp +
                                           (*(npy_cdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_double *)data_out)[0] = ((npy_double *)data0)[0] +
                                         ((npy_double *)data_out)[0];
        ((npy_double *)data_out)[1] = ((npy_double *)data0)[1] +
                                         ((npy_double *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
cdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_double *)data_out + 2*6)[0] =
                                    ((npy_double *)data0 + 2*6)[0] +
                                    ((npy_double *)data_out + 2*6)[0];
            ((npy_double *)data_out + 2*6)[1] =
                                    ((npy_double *)data0 + 2*6)[1] +
                                    ((npy_double *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_double *)data_out + 2*5)[0] =
                                    ((npy_double *)data0 + 2*5)[0] +
                                    ((npy_double *)data_out + 2*5)[0];
            ((npy_double *)data_out + 2*5)[1] =
                                    ((npy_double *)data0 + 2*5)[1] +
                                    ((npy_double *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_double *)data_out + 2*4)[0] =
                                    ((npy_double *)data0 + 2*4)[0] +
                                    ((npy_double *)data_out + 2*4)[0];
            ((npy_double *)data_out + 2*4)[1] =
                                    ((npy_double *)data0 + 2*4)[1] +
                                    ((npy_double *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_double *)data_out + 2*3)[0] =
                                    ((npy_double *)data0 + 2*3)[0] +
                                    ((npy_double *)data_out + 2*3)[0];
            ((npy_double *)data_out + 2*3)[1] =
                                    ((npy_double *)data0 + 2*3)[1] +
                                    ((npy_double *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_double *)data_out + 2*2)[0] =
                                    ((npy_double *)data0 + 2*2)[0] +
                                    ((npy_double *)data_out + 2*2)[0];
            ((npy_double *)data_out + 2*2)[1] =
                                    ((npy_double *)data0 + 2*2)[1] +
                                    ((npy_double *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_double *)data_out + 2*1)[0] =
                                    ((npy_double *)data0 + 2*1)[0] +
                                    ((npy_double *)data_out + 2*1)[0];
            ((npy_double *)data_out + 2*1)[1] =
                                    ((npy_double *)data0 + 2*1)[1] +
                                    ((npy_double *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_double *)data_out + 2*0)[0] =
                                    ((npy_double *)data0 + 2*0)[0] +
                                    ((npy_double *)data_out + 2*0)[0];
            ((npy_double *)data_out + 2*0)[1] =
                                    ((npy_double *)data0 + 2*0)[1] +
                                    ((npy_double *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_double *)data_out + 2*0)[0] =
                                ((npy_double *)data0 + 2*0)[0] +
                                ((npy_double *)data_out + 2*0)[0];
        ((npy_double *)data_out + 2*0)[1] =
                                ((npy_double *)data0 + 2*0)[1] +
                                ((npy_double *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_double *)data_out + 2*1)[0] =
                                ((npy_double *)data0 + 2*1)[0] +
                                ((npy_double *)data_out + 2*1)[0];
        ((npy_double *)data_out + 2*1)[1] =
                                ((npy_double *)data0 + 2*1)[1] +
                                ((npy_double *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_double *)data_out + 2*2)[0] =
                                ((npy_double *)data0 + 2*2)[0] +
                                ((npy_double *)data_out + 2*2)[0];
        ((npy_double *)data_out + 2*2)[1] =
                                ((npy_double *)data0 + 2*2)[1] +
                                ((npy_double *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_double *)data_out + 2*3)[0] =
                                ((npy_double *)data0 + 2*3)[0] +
                                ((npy_double *)data_out + 2*3)[0];
        ((npy_double *)data_out + 2*3)[1] =
                                ((npy_double *)data0 + 2*3)[1] +
                                ((npy_double *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_double *)data_out + 2*4)[0] =
                                ((npy_double *)data0 + 2*4)[0] +
                                ((npy_double *)data_out + 2*4)[0];
        ((npy_double *)data_out + 2*4)[1] =
                                ((npy_double *)data0 + 2*4)[1] +
                                ((npy_double *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_double *)data_out + 2*5)[0] =
                                ((npy_double *)data0 + 2*5)[0] +
                                ((npy_double *)data_out + 2*5)[0];
        ((npy_double *)data_out + 2*5)[1] =
                                ((npy_double *)data0 + 2*5)[1] +
                                ((npy_double *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_double *)data_out + 2*6)[0] =
                                ((npy_double *)data0 + 2*6)[0] +
                                ((npy_double *)data_out + 2*6)[0];
        ((npy_double *)data_out + 2*6)[1] =
                                ((npy_double *)data0 + 2*6)[1] +
                                ((npy_double *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_double *)data_out + 2*7)[0] =
                                ((npy_double *)data0 + 2*7)[0] +
                                ((npy_double *)data_out + 2*7)[0];
        ((npy_double *)data_out + 2*7)[1] =
                                ((npy_double *)data0 + 2*7)[1] +
                                ((npy_double *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
cdouble_sum_of_products_muladd(npy_cdouble *data, npy_cdouble *data_out, npy_double scalar, npy_intp count)
{
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;
    const npyv_f64 v_scalar = npyv_setall_f64(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_loada_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_loada_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_loada_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_loada_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_f64 b0 = npyv_load_f64(data + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 312
            npyv_f64 b1 = npyv_load_f64(data + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 312
            npyv_f64 b2 = npyv_load_f64(data + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 312
            npyv_f64 b3 = npyv_load_f64(data + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 318
            npyv_f64 abc0 = npyv_muladd_f64(v_scalar, b0, c0);
            
#line 318
            npyv_f64 abc1 = npyv_muladd_f64(v_scalar, b1, c1);
            
#line 318
            npyv_f64 abc2 = npyv_muladd_f64(v_scalar, b2, c2);
            
#line 318
            npyv_f64 abc3 = npyv_muladd_f64(v_scalar, b3, c3);
            
            #line 323
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data, count);
        npyv_f64 b = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_double b0 = (data[0]);
        const npy_double c0 = (data_out[0]);
        
#line 340
        const npy_double b1 = (data[1]);
        const npy_double c1 = (data_out[1]);
        
#line 340
        const npy_double b2 = (data[2]);
        const npy_double c2 = (data_out[2]);
        
#line 340
        const npy_double b3 = (data[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 346
        const npy_double abc0 = scalar * b0 + c0;
        
#line 346
        const npy_double abc1 = scalar * b1 + c1;
        
#line 346
        const npy_double abc2 = scalar * b2 + c2;
        
#line 346
        const npy_double abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_double b = (*data);
        const npy_double c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_cdouble
}

static void
cdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_cdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_f64;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_loada_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_loada_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_loada_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_loada_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_storea_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            npyv_f64 c0 = npyv_load_f64(data_out + vstep * 0);
            
#line 390
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            npyv_f64 c1 = npyv_load_f64(data_out + vstep * 1);
            
#line 390
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            npyv_f64 c2 = npyv_load_f64(data_out + vstep * 2);
            
#line 390
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            npyv_f64 c3 = npyv_load_f64(data_out + vstep * 3);
            
            #line 397
            npyv_f64 abc0 = npyv_muladd_f64(a0, b0, c0);
            
#line 397
            npyv_f64 abc1 = npyv_muladd_f64(a1, b1, c1);
            
#line 397
            npyv_f64 abc2 = npyv_muladd_f64(a2, b2, c2);
            
#line 397
            npyv_f64 abc3 = npyv_muladd_f64(a3, b3, c3);
            
            #line 402
            npyv_store_f64(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_f64(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_f64(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_f64(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        npyv_f64 c = npyv_load_tillz_f64(data_out, count);
        npyv_store_till_f64(data_out, count, npyv_muladd_f64(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_double a0 = (data0[0]);
        const npy_double b0 = (data1[0]);
        const npy_double c0 = (data_out[0]);
        
#line 420
        const npy_double a1 = (data0[1]);
        const npy_double b1 = (data1[1]);
        const npy_double c1 = (data_out[1]);
        
#line 420
        const npy_double a2 = (data0[2]);
        const npy_double b2 = (data1[2]);
        const npy_double c2 = (data_out[2]);
        
#line 420
        const npy_double a3 = (data0[3]);
        const npy_double b3 = (data1[3]);
        const npy_double c3 = (data_out[3]);
        
        #line 427
        const npy_double abc0 = a0 * b0 + c0;
        
#line 427
        const npy_double abc1 = a1 * b1 + c1;
        
#line 427
        const npy_double abc2 = a2 * b2 + c2;
        
#line 427
        const npy_double abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        const npy_double c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_cdouble

}

/* Some extra specializations for the two operand case */
static void
cdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value0 = (*(npy_cdouble *)dataptr[0]);
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    cdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
cdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_double value1 = (*(npy_cdouble *)dataptr[1]);
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    cdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_double accum = 0;

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_cdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_f64;
    npyv_f64 v_accum = npyv_zero_f64();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_loada_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_loada_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_loada_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_loada_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_loada_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_loada_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_loada_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_loada_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_f64 a0 = npyv_load_f64(data0 + vstep * 0);
            npyv_f64 b0 = npyv_load_f64(data1 + vstep * 0);
            
#line 501
            npyv_f64 a1 = npyv_load_f64(data0 + vstep * 1);
            npyv_f64 b1 = npyv_load_f64(data1 + vstep * 1);
            
#line 501
            npyv_f64 a2 = npyv_load_f64(data0 + vstep * 2);
            npyv_f64 b2 = npyv_load_f64(data1 + vstep * 2);
            
#line 501
            npyv_f64 a3 = npyv_load_f64(data0 + vstep * 3);
            npyv_f64 b3 = npyv_load_f64(data1 + vstep * 3);
            
            npyv_f64 ab3 = npyv_muladd_f64(a3, b3, v_accum);
            npyv_f64 ab2 = npyv_muladd_f64(a2, b2, ab3);
            npyv_f64 ab1 = npyv_muladd_f64(a1, b1, ab2);
                   v_accum = npyv_muladd_f64(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_f64 a = npyv_load_tillz_f64(data0, count);
        npyv_f64 b = npyv_load_tillz_f64(data1, count);
        v_accum = npyv_muladd_f64(a, b, v_accum);
    }
    accum = npyv_sum_f64(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_double ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_double ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_double ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_double ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_double a = (*data0);
        const npy_double b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_cdouble
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_double value0 = (*(npy_cdouble *)dataptr[0]);
    npy_double accum = cdouble_sum_of_arr(data1, count);
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_double value1 = (*(npy_cdouble *)dataptr[1]);
    npy_double accum = cdouble_sum_of_arr(data0, count);
    *(npy_cdouble *)dataptr[2] = ((*(npy_cdouble *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !1

static void
cdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_cdouble *data0 = (npy_cdouble *)dataptr[0];
    npy_cdouble *data1 = (npy_cdouble *)dataptr[1];
    npy_cdouble *data2 = (npy_cdouble *)dataptr[2];
    npy_cdouble *data_out = (npy_cdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
cdouble_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        *(npy_cdouble *)dataptr[nop] = (temp +
                                           (*(npy_cdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_cdouble);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_double *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[0];
        ((npy_double *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_double *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_cdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
cdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_cdouble *data = (npy_cdouble *)dataptr[0];
    npy_double accum = cdouble_sum_of_arr(data, count);
    *((npy_cdouble *)dataptr[1]) = (accum + (*((npy_cdouble *)dataptr[1])));
#else
    npy_double accum_re = 0, accum_im = 0;
    npy_double *data0 = (npy_double *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_double re01 = data0[0] + data0[2];
        const npy_double re23 = data0[4] + data0[6];
        const npy_double im13 = data0[1] + data0[3];
        const npy_double im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_double *)dataptr[1])[0] += accum_re;
    ((npy_double *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 1000 == 1 */

static void
cdouble_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_double accum_re = 0, accum_im = 0;
#else
    npy_double accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("cdouble_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 1000 == 1
        accum += (*(npy_cdouble *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_cdouble *)data0) *
                 (*(npy_cdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_cdouble *)data0) *
                 (*(npy_cdouble *)data1) *
                 (*(npy_cdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_double temp = (*(npy_cdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_cdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_double *)data0)[0];
        accum_im += ((npy_double *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_double re, im, tmp;
        int i;
        re = ((npy_double *)dataptr[0])[0];
        im = ((npy_double *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_double *)dataptr[i])[0] -
                  im * ((npy_double *)dataptr[i])[1];
            im = re * ((npy_double *)dataptr[i])[1] +
                 im * ((npy_double *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 1000 <= 3
    ((npy_double *)dataptr[1000])[0] += accum_re;
    ((npy_double *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_double *)dataptr[nop])[0] += accum_re;
    ((npy_double *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_cdouble *)dataptr[1000]) = (accum +
                                    (*((npy_cdouble *)dataptr[1000])));
#  else
    *((npy_cdouble *)dataptr[nop]) = (accum +
                                    (*((npy_cdouble *)dataptr[nop])));
#  endif
#endif

}




#line 74

#if !1
static NPY_GCC_OPT_3 npy_longdouble clongdouble_sum_of_arr(npy_clongdouble *data, npy_intp count)
{
    npy_longdouble accum = 0;
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data);
    const int vstep = npyv_nlanes_clongdouble;
    npyv_clongdouble v_accum = npyv_zero_clongdouble();
    const npy_intp vstepx4 = vstep * 4;

    #line 91
    if(is_aligned) {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_clongdouble a0 = npyv_loada_clongdouble(data + vstep * 0);
            
#line 96
            npyv_clongdouble a1 = npyv_loada_clongdouble(data + vstep * 1);
            
#line 96
            npyv_clongdouble a2 = npyv_loada_clongdouble(data + vstep * 2);
            
#line 96
            npyv_clongdouble a3 = npyv_loada_clongdouble(data + vstep * 3);
            
            npyv_clongdouble a01   = npyv_add_clongdouble(a0, a1);
            npyv_clongdouble a23   = npyv_add_clongdouble(a2, a3);
            npyv_clongdouble a0123 = npyv_add_clongdouble(a01, a23);
                     v_accum = npyv_add_clongdouble(a0123, v_accum);
        }
    }
    
#line 91
    else {
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
            #line 96
            npyv_clongdouble a0 = npyv_load_clongdouble(data + vstep * 0);
            
#line 96
            npyv_clongdouble a1 = npyv_load_clongdouble(data + vstep * 1);
            
#line 96
            npyv_clongdouble a2 = npyv_load_clongdouble(data + vstep * 2);
            
#line 96
            npyv_clongdouble a3 = npyv_load_clongdouble(data + vstep * 3);
            
            npyv_clongdouble a01   = npyv_add_clongdouble(a0, a1);
            npyv_clongdouble a23   = npyv_add_clongdouble(a2, a3);
            npyv_clongdouble a0123 = npyv_add_clongdouble(a01, a23);
                     v_accum = npyv_add_clongdouble(a0123, v_accum);
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data, count);
        v_accum = npyv_add_clongdouble(a, v_accum);
    }
    accum = npyv_sum_clongdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data += 4) {
        const npy_longdouble a01 = (*data) + (data[1]);
        const npy_longdouble a23 = (data[2]) + (data[3]);
        accum +=  a01 + a23;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data++) {
        accum += (*data);
    }
#endif // NPYV check for npy_clongdouble
    return accum;
}
#endif

#line 131
static void
clongdouble_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 == 1) || (1 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 == 1) || (1 <= 3 && !1)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_one (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 1 == 1
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1 == 2
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) *
                                         (*(npy_clongdouble *)data1) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1 == 3
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) *
                                         (*(npy_clongdouble *)data1) *
                                         (*(npy_clongdouble *)data2) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        *(npy_clongdouble *)dataptr[nop] = (temp +
                                           (*(npy_clongdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        ((npy_longdouble *)data_out)[0] = ((npy_longdouble *)data0)[0] +
                                         ((npy_longdouble *)data_out)[0];
        ((npy_longdouble *)data_out)[1] = ((npy_longdouble *)data0)[1] +
                                         ((npy_longdouble *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1 == 1

static void
clongdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longdouble *)data_out + 2*6)[0] =
                                    ((npy_longdouble *)data0 + 2*6)[0] +
                                    ((npy_longdouble *)data_out + 2*6)[0];
            ((npy_longdouble *)data_out + 2*6)[1] =
                                    ((npy_longdouble *)data0 + 2*6)[1] +
                                    ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longdouble *)data_out + 2*5)[0] =
                                    ((npy_longdouble *)data0 + 2*5)[0] +
                                    ((npy_longdouble *)data_out + 2*5)[0];
            ((npy_longdouble *)data_out + 2*5)[1] =
                                    ((npy_longdouble *)data0 + 2*5)[1] +
                                    ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longdouble *)data_out + 2*4)[0] =
                                    ((npy_longdouble *)data0 + 2*4)[0] +
                                    ((npy_longdouble *)data_out + 2*4)[0];
            ((npy_longdouble *)data_out + 2*4)[1] =
                                    ((npy_longdouble *)data0 + 2*4)[1] +
                                    ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longdouble *)data_out + 2*3)[0] =
                                    ((npy_longdouble *)data0 + 2*3)[0] +
                                    ((npy_longdouble *)data_out + 2*3)[0];
            ((npy_longdouble *)data_out + 2*3)[1] =
                                    ((npy_longdouble *)data0 + 2*3)[1] +
                                    ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longdouble *)data_out + 2*2)[0] =
                                    ((npy_longdouble *)data0 + 2*2)[0] +
                                    ((npy_longdouble *)data_out + 2*2)[0];
            ((npy_longdouble *)data_out + 2*2)[1] =
                                    ((npy_longdouble *)data0 + 2*2)[1] +
                                    ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longdouble *)data_out + 2*1)[0] =
                                    ((npy_longdouble *)data0 + 2*1)[0] +
                                    ((npy_longdouble *)data_out + 2*1)[0];
            ((npy_longdouble *)data_out + 2*1)[1] =
                                    ((npy_longdouble *)data0 + 2*1)[1] +
                                    ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longdouble *)data_out + 2*0)[0] =
                                    ((npy_longdouble *)data0 + 2*0)[0] +
                                    ((npy_longdouble *)data_out + 2*0)[0];
            ((npy_longdouble *)data_out + 2*0)[1] =
                                    ((npy_longdouble *)data0 + 2*0)[1] +
                                    ((npy_longdouble *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*0)[0] =
                                ((npy_longdouble *)data0 + 2*0)[0] +
                                ((npy_longdouble *)data_out + 2*0)[0];
        ((npy_longdouble *)data_out + 2*0)[1] =
                                ((npy_longdouble *)data0 + 2*0)[1] +
                                ((npy_longdouble *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*1)[0] =
                                ((npy_longdouble *)data0 + 2*1)[0] +
                                ((npy_longdouble *)data_out + 2*1)[0];
        ((npy_longdouble *)data_out + 2*1)[1] =
                                ((npy_longdouble *)data0 + 2*1)[1] +
                                ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*2)[0] =
                                ((npy_longdouble *)data0 + 2*2)[0] +
                                ((npy_longdouble *)data_out + 2*2)[0];
        ((npy_longdouble *)data_out + 2*2)[1] =
                                ((npy_longdouble *)data0 + 2*2)[1] +
                                ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*3)[0] =
                                ((npy_longdouble *)data0 + 2*3)[0] +
                                ((npy_longdouble *)data_out + 2*3)[0];
        ((npy_longdouble *)data_out + 2*3)[1] =
                                ((npy_longdouble *)data0 + 2*3)[1] +
                                ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*4)[0] =
                                ((npy_longdouble *)data0 + 2*4)[0] +
                                ((npy_longdouble *)data_out + 2*4)[0];
        ((npy_longdouble *)data_out + 2*4)[1] =
                                ((npy_longdouble *)data0 + 2*4)[1] +
                                ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*5)[0] =
                                ((npy_longdouble *)data0 + 2*5)[0] +
                                ((npy_longdouble *)data_out + 2*5)[0];
        ((npy_longdouble *)data_out + 2*5)[1] =
                                ((npy_longdouble *)data0 + 2*5)[1] +
                                ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*6)[0] =
                                ((npy_longdouble *)data0 + 2*6)[0] +
                                ((npy_longdouble *)data_out + 2*6)[0];
        ((npy_longdouble *)data_out + 2*6)[1] =
                                ((npy_longdouble *)data0 + 2*6)[1] +
                                ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*7)[0] =
                                ((npy_longdouble *)data0 + 2*7)[0] +
                                ((npy_longdouble *)data_out + 2*7)[0];
        ((npy_longdouble *)data_out + 2*7)[1] =
                                ((npy_longdouble *)data0 + 2*7)[1] +
                                ((npy_longdouble *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_muladd(npy_clongdouble *data, npy_clongdouble *data_out, npy_longdouble scalar, npy_intp count)
{
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_clongdouble;
    const npyv_clongdouble v_scalar = npyv_setall_clongdouble(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_clongdouble b0 = npyv_loada_clongdouble(data + vstep * 0);
            npyv_clongdouble c0 = npyv_loada_clongdouble(data_out + vstep * 0);
            
#line 312
            npyv_clongdouble b1 = npyv_loada_clongdouble(data + vstep * 1);
            npyv_clongdouble c1 = npyv_loada_clongdouble(data_out + vstep * 1);
            
#line 312
            npyv_clongdouble b2 = npyv_loada_clongdouble(data + vstep * 2);
            npyv_clongdouble c2 = npyv_loada_clongdouble(data_out + vstep * 2);
            
#line 312
            npyv_clongdouble b3 = npyv_loada_clongdouble(data + vstep * 3);
            npyv_clongdouble c3 = npyv_loada_clongdouble(data_out + vstep * 3);
            
            #line 318
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(v_scalar, b0, c0);
            
#line 318
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(v_scalar, b1, c1);
            
#line 318
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(v_scalar, b2, c2);
            
#line 318
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_clongdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_clongdouble b0 = npyv_load_clongdouble(data + vstep * 0);
            npyv_clongdouble c0 = npyv_load_clongdouble(data_out + vstep * 0);
            
#line 312
            npyv_clongdouble b1 = npyv_load_clongdouble(data + vstep * 1);
            npyv_clongdouble c1 = npyv_load_clongdouble(data_out + vstep * 1);
            
#line 312
            npyv_clongdouble b2 = npyv_load_clongdouble(data + vstep * 2);
            npyv_clongdouble c2 = npyv_load_clongdouble(data_out + vstep * 2);
            
#line 312
            npyv_clongdouble b3 = npyv_load_clongdouble(data + vstep * 3);
            npyv_clongdouble c3 = npyv_load_clongdouble(data_out + vstep * 3);
            
            #line 318
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(v_scalar, b0, c0);
            
#line 318
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(v_scalar, b1, c1);
            
#line 318
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(v_scalar, b2, c2);
            
#line 318
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_store_clongdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data_out, count);
        npyv_store_till_clongdouble(data_out, count, npyv_muladd_clongdouble(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longdouble b0 = (data[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 340
        const npy_longdouble b1 = (data[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 340
        const npy_longdouble b2 = (data[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 340
        const npy_longdouble b3 = (data[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 346
        const npy_longdouble abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longdouble abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longdouble abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longdouble abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longdouble b = (*data);
        const npy_longdouble c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_clongdouble
}

static void
clongdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_clongdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_clongdouble;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_clongdouble a0 = npyv_loada_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_loada_clongdouble(data1 + vstep * 0);
            npyv_clongdouble c0 = npyv_loada_clongdouble(data_out + vstep * 0);
            
#line 390
            npyv_clongdouble a1 = npyv_loada_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_loada_clongdouble(data1 + vstep * 1);
            npyv_clongdouble c1 = npyv_loada_clongdouble(data_out + vstep * 1);
            
#line 390
            npyv_clongdouble a2 = npyv_loada_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_loada_clongdouble(data1 + vstep * 2);
            npyv_clongdouble c2 = npyv_loada_clongdouble(data_out + vstep * 2);
            
#line 390
            npyv_clongdouble a3 = npyv_loada_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_loada_clongdouble(data1 + vstep * 3);
            npyv_clongdouble c3 = npyv_loada_clongdouble(data_out + vstep * 3);
            
            #line 397
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(a0, b0, c0);
            
#line 397
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(a1, b1, c1);
            
#line 397
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(a2, b2, c2);
            
#line 397
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(a3, b3, c3);
            
            #line 402
            npyv_storea_clongdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_clongdouble a0 = npyv_load_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_load_clongdouble(data1 + vstep * 0);
            npyv_clongdouble c0 = npyv_load_clongdouble(data_out + vstep * 0);
            
#line 390
            npyv_clongdouble a1 = npyv_load_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_load_clongdouble(data1 + vstep * 1);
            npyv_clongdouble c1 = npyv_load_clongdouble(data_out + vstep * 1);
            
#line 390
            npyv_clongdouble a2 = npyv_load_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_load_clongdouble(data1 + vstep * 2);
            npyv_clongdouble c2 = npyv_load_clongdouble(data_out + vstep * 2);
            
#line 390
            npyv_clongdouble a3 = npyv_load_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_load_clongdouble(data1 + vstep * 3);
            npyv_clongdouble c3 = npyv_load_clongdouble(data_out + vstep * 3);
            
            #line 397
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(a0, b0, c0);
            
#line 397
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(a1, b1, c1);
            
#line 397
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(a2, b2, c2);
            
#line 397
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(a3, b3, c3);
            
            #line 402
            npyv_store_clongdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data0, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data1, count);
        npyv_clongdouble c = npyv_load_tillz_clongdouble(data_out, count);
        npyv_store_till_clongdouble(data_out, count, npyv_muladd_clongdouble(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longdouble a0 = (data0[0]);
        const npy_longdouble b0 = (data1[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 420
        const npy_longdouble a1 = (data0[1]);
        const npy_longdouble b1 = (data1[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 420
        const npy_longdouble a2 = (data0[2]);
        const npy_longdouble b2 = (data1[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 420
        const npy_longdouble a3 = (data0[3]);
        const npy_longdouble b3 = (data1[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 427
        const npy_longdouble abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longdouble abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longdouble abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longdouble abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        const npy_longdouble c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_clongdouble

}

/* Some extra specializations for the two operand case */
static void
clongdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value0 = (*(npy_clongdouble *)dataptr[0]);
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    clongdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
clongdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value1 = (*(npy_clongdouble *)dataptr[1]);
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    clongdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_longdouble accum = 0;

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_clongdouble;
    npyv_clongdouble v_accum = npyv_zero_clongdouble();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_clongdouble a0 = npyv_loada_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_loada_clongdouble(data1 + vstep * 0);
            
#line 501
            npyv_clongdouble a1 = npyv_loada_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_loada_clongdouble(data1 + vstep * 1);
            
#line 501
            npyv_clongdouble a2 = npyv_loada_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_loada_clongdouble(data1 + vstep * 2);
            
#line 501
            npyv_clongdouble a3 = npyv_loada_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_loada_clongdouble(data1 + vstep * 3);
            
            npyv_clongdouble ab3 = npyv_muladd_clongdouble(a3, b3, v_accum);
            npyv_clongdouble ab2 = npyv_muladd_clongdouble(a2, b2, ab3);
            npyv_clongdouble ab1 = npyv_muladd_clongdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_clongdouble(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_clongdouble a0 = npyv_load_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_load_clongdouble(data1 + vstep * 0);
            
#line 501
            npyv_clongdouble a1 = npyv_load_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_load_clongdouble(data1 + vstep * 1);
            
#line 501
            npyv_clongdouble a2 = npyv_load_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_load_clongdouble(data1 + vstep * 2);
            
#line 501
            npyv_clongdouble a3 = npyv_load_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_load_clongdouble(data1 + vstep * 3);
            
            npyv_clongdouble ab3 = npyv_muladd_clongdouble(a3, b3, v_accum);
            npyv_clongdouble ab2 = npyv_muladd_clongdouble(a2, b2, ab3);
            npyv_clongdouble ab1 = npyv_muladd_clongdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_clongdouble(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data0, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data1, count);
        v_accum = npyv_muladd_clongdouble(a, b, v_accum);
    }
    accum = npyv_sum_clongdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longdouble ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longdouble ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longdouble ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longdouble ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_clongdouble
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_longdouble value0 = (*(npy_clongdouble *)dataptr[0]);
    npy_longdouble accum = clongdouble_sum_of_arr(data1, count);
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_longdouble value1 = (*(npy_clongdouble *)dataptr[1]);
    npy_longdouble accum = clongdouble_sum_of_arr(data0, count);
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + value1 * accum);
}

#elif 1 == 3 && !1

static void
clongdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data2 = (npy_clongdouble *)dataptr[2];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1 > 3 || @complex */

static void
clongdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        *(npy_clongdouble *)dataptr[nop] = (temp +
                                           (*(npy_clongdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_clongdouble);
        }
#else /* complex */
#  if 1 <= 3
#    define _SUMPROD_NOP 1
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_clongdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1 */

#if 1 == 1

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_clongdouble *data = (npy_clongdouble *)dataptr[0];
    npy_longdouble accum = clongdouble_sum_of_arr(data, count);
    *((npy_clongdouble *)dataptr[1]) = (accum + (*((npy_clongdouble *)dataptr[1])));
#else
    npy_longdouble accum_re = 0, accum_im = 0;
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longdouble re01 = data0[0] + data0[2];
        const npy_longdouble re23 = data0[4] + data0[6];
        const npy_longdouble im13 = data0[1] + data0[3];
        const npy_longdouble im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 1 == 1 */

static void
clongdouble_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_longdouble accum_re = 0, accum_im = 0;
#else
    npy_longdouble accum = 0;
#endif

#if (1 == 1) || (1 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_outstride0_one (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 1 == 1
        accum += (*(npy_clongdouble *)data0);
        data0 += stride0;
#  elif 1 == 2
        accum += (*(npy_clongdouble *)data0) *
                 (*(npy_clongdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1 == 3
        accum += (*(npy_clongdouble *)data0) *
                 (*(npy_clongdouble *)data1) *
                 (*(npy_clongdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1 == 1
        accum_re += ((npy_longdouble *)data0)[0];
        accum_im += ((npy_longdouble *)data0)[1];
        data0 += stride0;
#  else
#    if 1 <= 3
#define _SUMPROD_NOP 1
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 1 <= 3
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#  else
    ((npy_longdouble *)dataptr[nop])[0] += accum_re;
    ((npy_longdouble *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1 <= 3
    *((npy_clongdouble *)dataptr[1]) = (accum +
                                    (*((npy_clongdouble *)dataptr[1])));
#  else
    *((npy_clongdouble *)dataptr[nop]) = (accum +
                                    (*((npy_clongdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
clongdouble_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 == 1) || (2 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 == 1) || (2 <= 3 && !1)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_two (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 2 == 1
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 2 == 2
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) *
                                         (*(npy_clongdouble *)data1) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 2 == 3
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) *
                                         (*(npy_clongdouble *)data1) *
                                         (*(npy_clongdouble *)data2) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        *(npy_clongdouble *)dataptr[nop] = (temp +
                                           (*(npy_clongdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        ((npy_longdouble *)data_out)[0] = ((npy_longdouble *)data0)[0] +
                                         ((npy_longdouble *)data_out)[0];
        ((npy_longdouble *)data_out)[1] = ((npy_longdouble *)data0)[1] +
                                         ((npy_longdouble *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 2 == 1

static void
clongdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longdouble *)data_out + 2*6)[0] =
                                    ((npy_longdouble *)data0 + 2*6)[0] +
                                    ((npy_longdouble *)data_out + 2*6)[0];
            ((npy_longdouble *)data_out + 2*6)[1] =
                                    ((npy_longdouble *)data0 + 2*6)[1] +
                                    ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longdouble *)data_out + 2*5)[0] =
                                    ((npy_longdouble *)data0 + 2*5)[0] +
                                    ((npy_longdouble *)data_out + 2*5)[0];
            ((npy_longdouble *)data_out + 2*5)[1] =
                                    ((npy_longdouble *)data0 + 2*5)[1] +
                                    ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longdouble *)data_out + 2*4)[0] =
                                    ((npy_longdouble *)data0 + 2*4)[0] +
                                    ((npy_longdouble *)data_out + 2*4)[0];
            ((npy_longdouble *)data_out + 2*4)[1] =
                                    ((npy_longdouble *)data0 + 2*4)[1] +
                                    ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longdouble *)data_out + 2*3)[0] =
                                    ((npy_longdouble *)data0 + 2*3)[0] +
                                    ((npy_longdouble *)data_out + 2*3)[0];
            ((npy_longdouble *)data_out + 2*3)[1] =
                                    ((npy_longdouble *)data0 + 2*3)[1] +
                                    ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longdouble *)data_out + 2*2)[0] =
                                    ((npy_longdouble *)data0 + 2*2)[0] +
                                    ((npy_longdouble *)data_out + 2*2)[0];
            ((npy_longdouble *)data_out + 2*2)[1] =
                                    ((npy_longdouble *)data0 + 2*2)[1] +
                                    ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longdouble *)data_out + 2*1)[0] =
                                    ((npy_longdouble *)data0 + 2*1)[0] +
                                    ((npy_longdouble *)data_out + 2*1)[0];
            ((npy_longdouble *)data_out + 2*1)[1] =
                                    ((npy_longdouble *)data0 + 2*1)[1] +
                                    ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longdouble *)data_out + 2*0)[0] =
                                    ((npy_longdouble *)data0 + 2*0)[0] +
                                    ((npy_longdouble *)data_out + 2*0)[0];
            ((npy_longdouble *)data_out + 2*0)[1] =
                                    ((npy_longdouble *)data0 + 2*0)[1] +
                                    ((npy_longdouble *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*0)[0] =
                                ((npy_longdouble *)data0 + 2*0)[0] +
                                ((npy_longdouble *)data_out + 2*0)[0];
        ((npy_longdouble *)data_out + 2*0)[1] =
                                ((npy_longdouble *)data0 + 2*0)[1] +
                                ((npy_longdouble *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*1)[0] =
                                ((npy_longdouble *)data0 + 2*1)[0] +
                                ((npy_longdouble *)data_out + 2*1)[0];
        ((npy_longdouble *)data_out + 2*1)[1] =
                                ((npy_longdouble *)data0 + 2*1)[1] +
                                ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*2)[0] =
                                ((npy_longdouble *)data0 + 2*2)[0] +
                                ((npy_longdouble *)data_out + 2*2)[0];
        ((npy_longdouble *)data_out + 2*2)[1] =
                                ((npy_longdouble *)data0 + 2*2)[1] +
                                ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*3)[0] =
                                ((npy_longdouble *)data0 + 2*3)[0] +
                                ((npy_longdouble *)data_out + 2*3)[0];
        ((npy_longdouble *)data_out + 2*3)[1] =
                                ((npy_longdouble *)data0 + 2*3)[1] +
                                ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*4)[0] =
                                ((npy_longdouble *)data0 + 2*4)[0] +
                                ((npy_longdouble *)data_out + 2*4)[0];
        ((npy_longdouble *)data_out + 2*4)[1] =
                                ((npy_longdouble *)data0 + 2*4)[1] +
                                ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*5)[0] =
                                ((npy_longdouble *)data0 + 2*5)[0] +
                                ((npy_longdouble *)data_out + 2*5)[0];
        ((npy_longdouble *)data_out + 2*5)[1] =
                                ((npy_longdouble *)data0 + 2*5)[1] +
                                ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*6)[0] =
                                ((npy_longdouble *)data0 + 2*6)[0] +
                                ((npy_longdouble *)data_out + 2*6)[0];
        ((npy_longdouble *)data_out + 2*6)[1] =
                                ((npy_longdouble *)data0 + 2*6)[1] +
                                ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*7)[0] =
                                ((npy_longdouble *)data0 + 2*7)[0] +
                                ((npy_longdouble *)data_out + 2*7)[0];
        ((npy_longdouble *)data_out + 2*7)[1] =
                                ((npy_longdouble *)data0 + 2*7)[1] +
                                ((npy_longdouble *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 2 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_muladd(npy_clongdouble *data, npy_clongdouble *data_out, npy_longdouble scalar, npy_intp count)
{
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_clongdouble;
    const npyv_clongdouble v_scalar = npyv_setall_clongdouble(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_clongdouble b0 = npyv_loada_clongdouble(data + vstep * 0);
            npyv_clongdouble c0 = npyv_loada_clongdouble(data_out + vstep * 0);
            
#line 312
            npyv_clongdouble b1 = npyv_loada_clongdouble(data + vstep * 1);
            npyv_clongdouble c1 = npyv_loada_clongdouble(data_out + vstep * 1);
            
#line 312
            npyv_clongdouble b2 = npyv_loada_clongdouble(data + vstep * 2);
            npyv_clongdouble c2 = npyv_loada_clongdouble(data_out + vstep * 2);
            
#line 312
            npyv_clongdouble b3 = npyv_loada_clongdouble(data + vstep * 3);
            npyv_clongdouble c3 = npyv_loada_clongdouble(data_out + vstep * 3);
            
            #line 318
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(v_scalar, b0, c0);
            
#line 318
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(v_scalar, b1, c1);
            
#line 318
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(v_scalar, b2, c2);
            
#line 318
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_clongdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_clongdouble b0 = npyv_load_clongdouble(data + vstep * 0);
            npyv_clongdouble c0 = npyv_load_clongdouble(data_out + vstep * 0);
            
#line 312
            npyv_clongdouble b1 = npyv_load_clongdouble(data + vstep * 1);
            npyv_clongdouble c1 = npyv_load_clongdouble(data_out + vstep * 1);
            
#line 312
            npyv_clongdouble b2 = npyv_load_clongdouble(data + vstep * 2);
            npyv_clongdouble c2 = npyv_load_clongdouble(data_out + vstep * 2);
            
#line 312
            npyv_clongdouble b3 = npyv_load_clongdouble(data + vstep * 3);
            npyv_clongdouble c3 = npyv_load_clongdouble(data_out + vstep * 3);
            
            #line 318
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(v_scalar, b0, c0);
            
#line 318
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(v_scalar, b1, c1);
            
#line 318
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(v_scalar, b2, c2);
            
#line 318
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_store_clongdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data_out, count);
        npyv_store_till_clongdouble(data_out, count, npyv_muladd_clongdouble(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longdouble b0 = (data[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 340
        const npy_longdouble b1 = (data[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 340
        const npy_longdouble b2 = (data[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 340
        const npy_longdouble b3 = (data[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 346
        const npy_longdouble abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longdouble abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longdouble abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longdouble abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longdouble b = (*data);
        const npy_longdouble c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_clongdouble
}

static void
clongdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_clongdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_clongdouble;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_clongdouble a0 = npyv_loada_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_loada_clongdouble(data1 + vstep * 0);
            npyv_clongdouble c0 = npyv_loada_clongdouble(data_out + vstep * 0);
            
#line 390
            npyv_clongdouble a1 = npyv_loada_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_loada_clongdouble(data1 + vstep * 1);
            npyv_clongdouble c1 = npyv_loada_clongdouble(data_out + vstep * 1);
            
#line 390
            npyv_clongdouble a2 = npyv_loada_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_loada_clongdouble(data1 + vstep * 2);
            npyv_clongdouble c2 = npyv_loada_clongdouble(data_out + vstep * 2);
            
#line 390
            npyv_clongdouble a3 = npyv_loada_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_loada_clongdouble(data1 + vstep * 3);
            npyv_clongdouble c3 = npyv_loada_clongdouble(data_out + vstep * 3);
            
            #line 397
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(a0, b0, c0);
            
#line 397
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(a1, b1, c1);
            
#line 397
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(a2, b2, c2);
            
#line 397
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(a3, b3, c3);
            
            #line 402
            npyv_storea_clongdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_clongdouble a0 = npyv_load_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_load_clongdouble(data1 + vstep * 0);
            npyv_clongdouble c0 = npyv_load_clongdouble(data_out + vstep * 0);
            
#line 390
            npyv_clongdouble a1 = npyv_load_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_load_clongdouble(data1 + vstep * 1);
            npyv_clongdouble c1 = npyv_load_clongdouble(data_out + vstep * 1);
            
#line 390
            npyv_clongdouble a2 = npyv_load_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_load_clongdouble(data1 + vstep * 2);
            npyv_clongdouble c2 = npyv_load_clongdouble(data_out + vstep * 2);
            
#line 390
            npyv_clongdouble a3 = npyv_load_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_load_clongdouble(data1 + vstep * 3);
            npyv_clongdouble c3 = npyv_load_clongdouble(data_out + vstep * 3);
            
            #line 397
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(a0, b0, c0);
            
#line 397
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(a1, b1, c1);
            
#line 397
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(a2, b2, c2);
            
#line 397
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(a3, b3, c3);
            
            #line 402
            npyv_store_clongdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data0, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data1, count);
        npyv_clongdouble c = npyv_load_tillz_clongdouble(data_out, count);
        npyv_store_till_clongdouble(data_out, count, npyv_muladd_clongdouble(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longdouble a0 = (data0[0]);
        const npy_longdouble b0 = (data1[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 420
        const npy_longdouble a1 = (data0[1]);
        const npy_longdouble b1 = (data1[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 420
        const npy_longdouble a2 = (data0[2]);
        const npy_longdouble b2 = (data1[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 420
        const npy_longdouble a3 = (data0[3]);
        const npy_longdouble b3 = (data1[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 427
        const npy_longdouble abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longdouble abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longdouble abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longdouble abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        const npy_longdouble c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_clongdouble

}

/* Some extra specializations for the two operand case */
static void
clongdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value0 = (*(npy_clongdouble *)dataptr[0]);
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    clongdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
clongdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value1 = (*(npy_clongdouble *)dataptr[1]);
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    clongdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_longdouble accum = 0;

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_clongdouble;
    npyv_clongdouble v_accum = npyv_zero_clongdouble();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_clongdouble a0 = npyv_loada_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_loada_clongdouble(data1 + vstep * 0);
            
#line 501
            npyv_clongdouble a1 = npyv_loada_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_loada_clongdouble(data1 + vstep * 1);
            
#line 501
            npyv_clongdouble a2 = npyv_loada_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_loada_clongdouble(data1 + vstep * 2);
            
#line 501
            npyv_clongdouble a3 = npyv_loada_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_loada_clongdouble(data1 + vstep * 3);
            
            npyv_clongdouble ab3 = npyv_muladd_clongdouble(a3, b3, v_accum);
            npyv_clongdouble ab2 = npyv_muladd_clongdouble(a2, b2, ab3);
            npyv_clongdouble ab1 = npyv_muladd_clongdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_clongdouble(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_clongdouble a0 = npyv_load_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_load_clongdouble(data1 + vstep * 0);
            
#line 501
            npyv_clongdouble a1 = npyv_load_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_load_clongdouble(data1 + vstep * 1);
            
#line 501
            npyv_clongdouble a2 = npyv_load_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_load_clongdouble(data1 + vstep * 2);
            
#line 501
            npyv_clongdouble a3 = npyv_load_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_load_clongdouble(data1 + vstep * 3);
            
            npyv_clongdouble ab3 = npyv_muladd_clongdouble(a3, b3, v_accum);
            npyv_clongdouble ab2 = npyv_muladd_clongdouble(a2, b2, ab3);
            npyv_clongdouble ab1 = npyv_muladd_clongdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_clongdouble(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data0, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data1, count);
        v_accum = npyv_muladd_clongdouble(a, b, v_accum);
    }
    accum = npyv_sum_clongdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longdouble ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longdouble ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longdouble ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longdouble ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_clongdouble
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_longdouble value0 = (*(npy_clongdouble *)dataptr[0]);
    npy_longdouble accum = clongdouble_sum_of_arr(data1, count);
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_longdouble value1 = (*(npy_clongdouble *)dataptr[1]);
    npy_longdouble accum = clongdouble_sum_of_arr(data0, count);
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + value1 * accum);
}

#elif 2 == 3 && !1

static void
clongdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data2 = (npy_clongdouble *)dataptr[2];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 2 > 3 || @complex */

static void
clongdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        *(npy_clongdouble *)dataptr[nop] = (temp +
                                           (*(npy_clongdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_clongdouble);
        }
#else /* complex */
#  if 2 <= 3
#    define _SUMPROD_NOP 2
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_clongdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 2 */

#if 2 == 1

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_clongdouble *data = (npy_clongdouble *)dataptr[0];
    npy_longdouble accum = clongdouble_sum_of_arr(data, count);
    *((npy_clongdouble *)dataptr[1]) = (accum + (*((npy_clongdouble *)dataptr[1])));
#else
    npy_longdouble accum_re = 0, accum_im = 0;
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longdouble re01 = data0[0] + data0[2];
        const npy_longdouble re23 = data0[4] + data0[6];
        const npy_longdouble im13 = data0[1] + data0[3];
        const npy_longdouble im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 2 == 1 */

static void
clongdouble_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_longdouble accum_re = 0, accum_im = 0;
#else
    npy_longdouble accum = 0;
#endif

#if (2 == 1) || (2 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_outstride0_two (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 2 == 1
        accum += (*(npy_clongdouble *)data0);
        data0 += stride0;
#  elif 2 == 2
        accum += (*(npy_clongdouble *)data0) *
                 (*(npy_clongdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 2 == 3
        accum += (*(npy_clongdouble *)data0) *
                 (*(npy_clongdouble *)data1) *
                 (*(npy_clongdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 2 == 1
        accum_re += ((npy_longdouble *)data0)[0];
        accum_im += ((npy_longdouble *)data0)[1];
        data0 += stride0;
#  else
#    if 2 <= 3
#define _SUMPROD_NOP 2
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 2 <= 3
    ((npy_longdouble *)dataptr[2])[0] += accum_re;
    ((npy_longdouble *)dataptr[2])[1] += accum_im;
#  else
    ((npy_longdouble *)dataptr[nop])[0] += accum_re;
    ((npy_longdouble *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 2 <= 3
    *((npy_clongdouble *)dataptr[2]) = (accum +
                                    (*((npy_clongdouble *)dataptr[2])));
#  else
    *((npy_clongdouble *)dataptr[nop]) = (accum +
                                    (*((npy_clongdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
clongdouble_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 == 1) || (3 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 == 1) || (3 <= 3 && !1)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_three (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 3 == 1
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 3 == 2
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) *
                                         (*(npy_clongdouble *)data1) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 3 == 3
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) *
                                         (*(npy_clongdouble *)data1) *
                                         (*(npy_clongdouble *)data2) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        *(npy_clongdouble *)dataptr[nop] = (temp +
                                           (*(npy_clongdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        ((npy_longdouble *)data_out)[0] = ((npy_longdouble *)data0)[0] +
                                         ((npy_longdouble *)data_out)[0];
        ((npy_longdouble *)data_out)[1] = ((npy_longdouble *)data0)[1] +
                                         ((npy_longdouble *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 3 == 1

static void
clongdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longdouble *)data_out + 2*6)[0] =
                                    ((npy_longdouble *)data0 + 2*6)[0] +
                                    ((npy_longdouble *)data_out + 2*6)[0];
            ((npy_longdouble *)data_out + 2*6)[1] =
                                    ((npy_longdouble *)data0 + 2*6)[1] +
                                    ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longdouble *)data_out + 2*5)[0] =
                                    ((npy_longdouble *)data0 + 2*5)[0] +
                                    ((npy_longdouble *)data_out + 2*5)[0];
            ((npy_longdouble *)data_out + 2*5)[1] =
                                    ((npy_longdouble *)data0 + 2*5)[1] +
                                    ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longdouble *)data_out + 2*4)[0] =
                                    ((npy_longdouble *)data0 + 2*4)[0] +
                                    ((npy_longdouble *)data_out + 2*4)[0];
            ((npy_longdouble *)data_out + 2*4)[1] =
                                    ((npy_longdouble *)data0 + 2*4)[1] +
                                    ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longdouble *)data_out + 2*3)[0] =
                                    ((npy_longdouble *)data0 + 2*3)[0] +
                                    ((npy_longdouble *)data_out + 2*3)[0];
            ((npy_longdouble *)data_out + 2*3)[1] =
                                    ((npy_longdouble *)data0 + 2*3)[1] +
                                    ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longdouble *)data_out + 2*2)[0] =
                                    ((npy_longdouble *)data0 + 2*2)[0] +
                                    ((npy_longdouble *)data_out + 2*2)[0];
            ((npy_longdouble *)data_out + 2*2)[1] =
                                    ((npy_longdouble *)data0 + 2*2)[1] +
                                    ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longdouble *)data_out + 2*1)[0] =
                                    ((npy_longdouble *)data0 + 2*1)[0] +
                                    ((npy_longdouble *)data_out + 2*1)[0];
            ((npy_longdouble *)data_out + 2*1)[1] =
                                    ((npy_longdouble *)data0 + 2*1)[1] +
                                    ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longdouble *)data_out + 2*0)[0] =
                                    ((npy_longdouble *)data0 + 2*0)[0] +
                                    ((npy_longdouble *)data_out + 2*0)[0];
            ((npy_longdouble *)data_out + 2*0)[1] =
                                    ((npy_longdouble *)data0 + 2*0)[1] +
                                    ((npy_longdouble *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*0)[0] =
                                ((npy_longdouble *)data0 + 2*0)[0] +
                                ((npy_longdouble *)data_out + 2*0)[0];
        ((npy_longdouble *)data_out + 2*0)[1] =
                                ((npy_longdouble *)data0 + 2*0)[1] +
                                ((npy_longdouble *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*1)[0] =
                                ((npy_longdouble *)data0 + 2*1)[0] +
                                ((npy_longdouble *)data_out + 2*1)[0];
        ((npy_longdouble *)data_out + 2*1)[1] =
                                ((npy_longdouble *)data0 + 2*1)[1] +
                                ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*2)[0] =
                                ((npy_longdouble *)data0 + 2*2)[0] +
                                ((npy_longdouble *)data_out + 2*2)[0];
        ((npy_longdouble *)data_out + 2*2)[1] =
                                ((npy_longdouble *)data0 + 2*2)[1] +
                                ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*3)[0] =
                                ((npy_longdouble *)data0 + 2*3)[0] +
                                ((npy_longdouble *)data_out + 2*3)[0];
        ((npy_longdouble *)data_out + 2*3)[1] =
                                ((npy_longdouble *)data0 + 2*3)[1] +
                                ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*4)[0] =
                                ((npy_longdouble *)data0 + 2*4)[0] +
                                ((npy_longdouble *)data_out + 2*4)[0];
        ((npy_longdouble *)data_out + 2*4)[1] =
                                ((npy_longdouble *)data0 + 2*4)[1] +
                                ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*5)[0] =
                                ((npy_longdouble *)data0 + 2*5)[0] +
                                ((npy_longdouble *)data_out + 2*5)[0];
        ((npy_longdouble *)data_out + 2*5)[1] =
                                ((npy_longdouble *)data0 + 2*5)[1] +
                                ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*6)[0] =
                                ((npy_longdouble *)data0 + 2*6)[0] +
                                ((npy_longdouble *)data_out + 2*6)[0];
        ((npy_longdouble *)data_out + 2*6)[1] =
                                ((npy_longdouble *)data0 + 2*6)[1] +
                                ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*7)[0] =
                                ((npy_longdouble *)data0 + 2*7)[0] +
                                ((npy_longdouble *)data_out + 2*7)[0];
        ((npy_longdouble *)data_out + 2*7)[1] =
                                ((npy_longdouble *)data0 + 2*7)[1] +
                                ((npy_longdouble *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 3 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_muladd(npy_clongdouble *data, npy_clongdouble *data_out, npy_longdouble scalar, npy_intp count)
{
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_clongdouble;
    const npyv_clongdouble v_scalar = npyv_setall_clongdouble(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_clongdouble b0 = npyv_loada_clongdouble(data + vstep * 0);
            npyv_clongdouble c0 = npyv_loada_clongdouble(data_out + vstep * 0);
            
#line 312
            npyv_clongdouble b1 = npyv_loada_clongdouble(data + vstep * 1);
            npyv_clongdouble c1 = npyv_loada_clongdouble(data_out + vstep * 1);
            
#line 312
            npyv_clongdouble b2 = npyv_loada_clongdouble(data + vstep * 2);
            npyv_clongdouble c2 = npyv_loada_clongdouble(data_out + vstep * 2);
            
#line 312
            npyv_clongdouble b3 = npyv_loada_clongdouble(data + vstep * 3);
            npyv_clongdouble c3 = npyv_loada_clongdouble(data_out + vstep * 3);
            
            #line 318
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(v_scalar, b0, c0);
            
#line 318
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(v_scalar, b1, c1);
            
#line 318
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(v_scalar, b2, c2);
            
#line 318
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_clongdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_clongdouble b0 = npyv_load_clongdouble(data + vstep * 0);
            npyv_clongdouble c0 = npyv_load_clongdouble(data_out + vstep * 0);
            
#line 312
            npyv_clongdouble b1 = npyv_load_clongdouble(data + vstep * 1);
            npyv_clongdouble c1 = npyv_load_clongdouble(data_out + vstep * 1);
            
#line 312
            npyv_clongdouble b2 = npyv_load_clongdouble(data + vstep * 2);
            npyv_clongdouble c2 = npyv_load_clongdouble(data_out + vstep * 2);
            
#line 312
            npyv_clongdouble b3 = npyv_load_clongdouble(data + vstep * 3);
            npyv_clongdouble c3 = npyv_load_clongdouble(data_out + vstep * 3);
            
            #line 318
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(v_scalar, b0, c0);
            
#line 318
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(v_scalar, b1, c1);
            
#line 318
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(v_scalar, b2, c2);
            
#line 318
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_store_clongdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data_out, count);
        npyv_store_till_clongdouble(data_out, count, npyv_muladd_clongdouble(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longdouble b0 = (data[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 340
        const npy_longdouble b1 = (data[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 340
        const npy_longdouble b2 = (data[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 340
        const npy_longdouble b3 = (data[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 346
        const npy_longdouble abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longdouble abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longdouble abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longdouble abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longdouble b = (*data);
        const npy_longdouble c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_clongdouble
}

static void
clongdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_clongdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_clongdouble;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_clongdouble a0 = npyv_loada_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_loada_clongdouble(data1 + vstep * 0);
            npyv_clongdouble c0 = npyv_loada_clongdouble(data_out + vstep * 0);
            
#line 390
            npyv_clongdouble a1 = npyv_loada_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_loada_clongdouble(data1 + vstep * 1);
            npyv_clongdouble c1 = npyv_loada_clongdouble(data_out + vstep * 1);
            
#line 390
            npyv_clongdouble a2 = npyv_loada_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_loada_clongdouble(data1 + vstep * 2);
            npyv_clongdouble c2 = npyv_loada_clongdouble(data_out + vstep * 2);
            
#line 390
            npyv_clongdouble a3 = npyv_loada_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_loada_clongdouble(data1 + vstep * 3);
            npyv_clongdouble c3 = npyv_loada_clongdouble(data_out + vstep * 3);
            
            #line 397
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(a0, b0, c0);
            
#line 397
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(a1, b1, c1);
            
#line 397
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(a2, b2, c2);
            
#line 397
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(a3, b3, c3);
            
            #line 402
            npyv_storea_clongdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_clongdouble a0 = npyv_load_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_load_clongdouble(data1 + vstep * 0);
            npyv_clongdouble c0 = npyv_load_clongdouble(data_out + vstep * 0);
            
#line 390
            npyv_clongdouble a1 = npyv_load_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_load_clongdouble(data1 + vstep * 1);
            npyv_clongdouble c1 = npyv_load_clongdouble(data_out + vstep * 1);
            
#line 390
            npyv_clongdouble a2 = npyv_load_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_load_clongdouble(data1 + vstep * 2);
            npyv_clongdouble c2 = npyv_load_clongdouble(data_out + vstep * 2);
            
#line 390
            npyv_clongdouble a3 = npyv_load_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_load_clongdouble(data1 + vstep * 3);
            npyv_clongdouble c3 = npyv_load_clongdouble(data_out + vstep * 3);
            
            #line 397
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(a0, b0, c0);
            
#line 397
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(a1, b1, c1);
            
#line 397
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(a2, b2, c2);
            
#line 397
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(a3, b3, c3);
            
            #line 402
            npyv_store_clongdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data0, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data1, count);
        npyv_clongdouble c = npyv_load_tillz_clongdouble(data_out, count);
        npyv_store_till_clongdouble(data_out, count, npyv_muladd_clongdouble(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longdouble a0 = (data0[0]);
        const npy_longdouble b0 = (data1[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 420
        const npy_longdouble a1 = (data0[1]);
        const npy_longdouble b1 = (data1[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 420
        const npy_longdouble a2 = (data0[2]);
        const npy_longdouble b2 = (data1[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 420
        const npy_longdouble a3 = (data0[3]);
        const npy_longdouble b3 = (data1[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 427
        const npy_longdouble abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longdouble abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longdouble abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longdouble abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        const npy_longdouble c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_clongdouble

}

/* Some extra specializations for the two operand case */
static void
clongdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value0 = (*(npy_clongdouble *)dataptr[0]);
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    clongdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
clongdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value1 = (*(npy_clongdouble *)dataptr[1]);
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    clongdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_longdouble accum = 0;

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_clongdouble;
    npyv_clongdouble v_accum = npyv_zero_clongdouble();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_clongdouble a0 = npyv_loada_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_loada_clongdouble(data1 + vstep * 0);
            
#line 501
            npyv_clongdouble a1 = npyv_loada_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_loada_clongdouble(data1 + vstep * 1);
            
#line 501
            npyv_clongdouble a2 = npyv_loada_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_loada_clongdouble(data1 + vstep * 2);
            
#line 501
            npyv_clongdouble a3 = npyv_loada_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_loada_clongdouble(data1 + vstep * 3);
            
            npyv_clongdouble ab3 = npyv_muladd_clongdouble(a3, b3, v_accum);
            npyv_clongdouble ab2 = npyv_muladd_clongdouble(a2, b2, ab3);
            npyv_clongdouble ab1 = npyv_muladd_clongdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_clongdouble(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_clongdouble a0 = npyv_load_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_load_clongdouble(data1 + vstep * 0);
            
#line 501
            npyv_clongdouble a1 = npyv_load_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_load_clongdouble(data1 + vstep * 1);
            
#line 501
            npyv_clongdouble a2 = npyv_load_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_load_clongdouble(data1 + vstep * 2);
            
#line 501
            npyv_clongdouble a3 = npyv_load_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_load_clongdouble(data1 + vstep * 3);
            
            npyv_clongdouble ab3 = npyv_muladd_clongdouble(a3, b3, v_accum);
            npyv_clongdouble ab2 = npyv_muladd_clongdouble(a2, b2, ab3);
            npyv_clongdouble ab1 = npyv_muladd_clongdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_clongdouble(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data0, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data1, count);
        v_accum = npyv_muladd_clongdouble(a, b, v_accum);
    }
    accum = npyv_sum_clongdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longdouble ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longdouble ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longdouble ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longdouble ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_clongdouble
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_longdouble value0 = (*(npy_clongdouble *)dataptr[0]);
    npy_longdouble accum = clongdouble_sum_of_arr(data1, count);
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_longdouble value1 = (*(npy_clongdouble *)dataptr[1]);
    npy_longdouble accum = clongdouble_sum_of_arr(data0, count);
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + value1 * accum);
}

#elif 3 == 3 && !1

static void
clongdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data2 = (npy_clongdouble *)dataptr[2];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 3 > 3 || @complex */

static void
clongdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        *(npy_clongdouble *)dataptr[nop] = (temp +
                                           (*(npy_clongdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_clongdouble);
        }
#else /* complex */
#  if 3 <= 3
#    define _SUMPROD_NOP 3
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_clongdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 3 */

#if 3 == 1

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_clongdouble *data = (npy_clongdouble *)dataptr[0];
    npy_longdouble accum = clongdouble_sum_of_arr(data, count);
    *((npy_clongdouble *)dataptr[1]) = (accum + (*((npy_clongdouble *)dataptr[1])));
#else
    npy_longdouble accum_re = 0, accum_im = 0;
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longdouble re01 = data0[0] + data0[2];
        const npy_longdouble re23 = data0[4] + data0[6];
        const npy_longdouble im13 = data0[1] + data0[3];
        const npy_longdouble im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 3 == 1 */

static void
clongdouble_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_longdouble accum_re = 0, accum_im = 0;
#else
    npy_longdouble accum = 0;
#endif

#if (3 == 1) || (3 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_outstride0_three (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 3 == 1
        accum += (*(npy_clongdouble *)data0);
        data0 += stride0;
#  elif 3 == 2
        accum += (*(npy_clongdouble *)data0) *
                 (*(npy_clongdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 3 == 3
        accum += (*(npy_clongdouble *)data0) *
                 (*(npy_clongdouble *)data1) *
                 (*(npy_clongdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 3 == 1
        accum_re += ((npy_longdouble *)data0)[0];
        accum_im += ((npy_longdouble *)data0)[1];
        data0 += stride0;
#  else
#    if 3 <= 3
#define _SUMPROD_NOP 3
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 3 <= 3
    ((npy_longdouble *)dataptr[3])[0] += accum_re;
    ((npy_longdouble *)dataptr[3])[1] += accum_im;
#  else
    ((npy_longdouble *)dataptr[nop])[0] += accum_re;
    ((npy_longdouble *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 3 <= 3
    *((npy_clongdouble *)dataptr[3]) = (accum +
                                    (*((npy_clongdouble *)dataptr[3])));
#  else
    *((npy_clongdouble *)dataptr[nop]) = (accum +
                                    (*((npy_clongdouble *)dataptr[nop])));
#  endif
#endif

}


#line 131
static void
clongdouble_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 == 1) || (1000 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 == 1) || (1000 <= 3 && !1)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_any (%d)\n", (int)count);

    while (count--) {
#if !1
#  if 1000 == 1
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data_out += stride_out;
#  elif 1000 == 2
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) *
                                         (*(npy_clongdouble *)data1) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#  elif 1000 == 3
        *(npy_clongdouble *)data_out = ((*(npy_clongdouble *)data0) *
                                         (*(npy_clongdouble *)data1) *
                                         (*(npy_clongdouble *)data2) +
                                         (*(npy_clongdouble *)data_out));
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#  else
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        *(npy_clongdouble *)dataptr[nop] = (temp +
                                           (*(npy_clongdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        ((npy_longdouble *)data_out)[0] = ((npy_longdouble *)data0)[0] +
                                         ((npy_longdouble *)data_out)[0];
        ((npy_longdouble *)data_out)[1] = ((npy_longdouble *)data0)[1] +
                                         ((npy_longdouble *)data_out)[1];
        data0 += stride0;
        data_out += stride_out;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }
}

#if 1000 == 1

static void
clongdouble_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[1];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_one (%d)\n",
                                                            (int)count);

/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 246
        case 6+1:
#if !1
            data_out[6] = ((data0[6]) +
                                 (data_out[6]));
#else
            ((npy_longdouble *)data_out + 2*6)[0] =
                                    ((npy_longdouble *)data0 + 2*6)[0] +
                                    ((npy_longdouble *)data_out + 2*6)[0];
            ((npy_longdouble *)data_out + 2*6)[1] =
                                    ((npy_longdouble *)data0 + 2*6)[1] +
                                    ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 246
        case 5+1:
#if !1
            data_out[5] = ((data0[5]) +
                                 (data_out[5]));
#else
            ((npy_longdouble *)data_out + 2*5)[0] =
                                    ((npy_longdouble *)data0 + 2*5)[0] +
                                    ((npy_longdouble *)data_out + 2*5)[0];
            ((npy_longdouble *)data_out + 2*5)[1] =
                                    ((npy_longdouble *)data0 + 2*5)[1] +
                                    ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 246
        case 4+1:
#if !1
            data_out[4] = ((data0[4]) +
                                 (data_out[4]));
#else
            ((npy_longdouble *)data_out + 2*4)[0] =
                                    ((npy_longdouble *)data0 + 2*4)[0] +
                                    ((npy_longdouble *)data_out + 2*4)[0];
            ((npy_longdouble *)data_out + 2*4)[1] =
                                    ((npy_longdouble *)data0 + 2*4)[1] +
                                    ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 246
        case 3+1:
#if !1
            data_out[3] = ((data0[3]) +
                                 (data_out[3]));
#else
            ((npy_longdouble *)data_out + 2*3)[0] =
                                    ((npy_longdouble *)data0 + 2*3)[0] +
                                    ((npy_longdouble *)data_out + 2*3)[0];
            ((npy_longdouble *)data_out + 2*3)[1] =
                                    ((npy_longdouble *)data0 + 2*3)[1] +
                                    ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 246
        case 2+1:
#if !1
            data_out[2] = ((data0[2]) +
                                 (data_out[2]));
#else
            ((npy_longdouble *)data_out + 2*2)[0] =
                                    ((npy_longdouble *)data0 + 2*2)[0] +
                                    ((npy_longdouble *)data_out + 2*2)[0];
            ((npy_longdouble *)data_out + 2*2)[1] =
                                    ((npy_longdouble *)data0 + 2*2)[1] +
                                    ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 246
        case 1+1:
#if !1
            data_out[1] = ((data0[1]) +
                                 (data_out[1]));
#else
            ((npy_longdouble *)data_out + 2*1)[0] =
                                    ((npy_longdouble *)data0 + 2*1)[0] +
                                    ((npy_longdouble *)data_out + 2*1)[0];
            ((npy_longdouble *)data_out + 2*1)[1] =
                                    ((npy_longdouble *)data0 + 2*1)[1] +
                                    ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 246
        case 0+1:
#if !1
            data_out[0] = ((data0[0]) +
                                 (data_out[0]));
#else
            ((npy_longdouble *)data_out + 2*0)[0] =
                                    ((npy_longdouble *)data0 + 2*0)[0] +
                                    ((npy_longdouble *)data_out + 2*0)[0];
            ((npy_longdouble *)data_out + 2*0)[1] =
                                    ((npy_longdouble *)data0 + 2*0)[1] +
                                    ((npy_longdouble *)data_out + 2*0)[1];
#endif

        case 0:
            return;
    }

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 270
#if !1
        data_out[0] = ((data0[0]) +
                             (data_out[0]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*0)[0] =
                                ((npy_longdouble *)data0 + 2*0)[0] +
                                ((npy_longdouble *)data_out + 2*0)[0];
        ((npy_longdouble *)data_out + 2*0)[1] =
                                ((npy_longdouble *)data0 + 2*0)[1] +
                                ((npy_longdouble *)data_out + 2*0)[1];
#endif

#line 270
#if !1
        data_out[1] = ((data0[1]) +
                             (data_out[1]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*1)[0] =
                                ((npy_longdouble *)data0 + 2*1)[0] +
                                ((npy_longdouble *)data_out + 2*1)[0];
        ((npy_longdouble *)data_out + 2*1)[1] =
                                ((npy_longdouble *)data0 + 2*1)[1] +
                                ((npy_longdouble *)data_out + 2*1)[1];
#endif

#line 270
#if !1
        data_out[2] = ((data0[2]) +
                             (data_out[2]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*2)[0] =
                                ((npy_longdouble *)data0 + 2*2)[0] +
                                ((npy_longdouble *)data_out + 2*2)[0];
        ((npy_longdouble *)data_out + 2*2)[1] =
                                ((npy_longdouble *)data0 + 2*2)[1] +
                                ((npy_longdouble *)data_out + 2*2)[1];
#endif

#line 270
#if !1
        data_out[3] = ((data0[3]) +
                             (data_out[3]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*3)[0] =
                                ((npy_longdouble *)data0 + 2*3)[0] +
                                ((npy_longdouble *)data_out + 2*3)[0];
        ((npy_longdouble *)data_out + 2*3)[1] =
                                ((npy_longdouble *)data0 + 2*3)[1] +
                                ((npy_longdouble *)data_out + 2*3)[1];
#endif

#line 270
#if !1
        data_out[4] = ((data0[4]) +
                             (data_out[4]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*4)[0] =
                                ((npy_longdouble *)data0 + 2*4)[0] +
                                ((npy_longdouble *)data_out + 2*4)[0];
        ((npy_longdouble *)data_out + 2*4)[1] =
                                ((npy_longdouble *)data0 + 2*4)[1] +
                                ((npy_longdouble *)data_out + 2*4)[1];
#endif

#line 270
#if !1
        data_out[5] = ((data0[5]) +
                             (data_out[5]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*5)[0] =
                                ((npy_longdouble *)data0 + 2*5)[0] +
                                ((npy_longdouble *)data_out + 2*5)[0];
        ((npy_longdouble *)data_out + 2*5)[1] =
                                ((npy_longdouble *)data0 + 2*5)[1] +
                                ((npy_longdouble *)data_out + 2*5)[1];
#endif

#line 270
#if !1
        data_out[6] = ((data0[6]) +
                             (data_out[6]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*6)[0] =
                                ((npy_longdouble *)data0 + 2*6)[0] +
                                ((npy_longdouble *)data_out + 2*6)[0];
        ((npy_longdouble *)data_out + 2*6)[1] =
                                ((npy_longdouble *)data0 + 2*6)[1] +
                                ((npy_longdouble *)data_out + 2*6)[1];
#endif

#line 270
#if !1
        data_out[7] = ((data0[7]) +
                             (data_out[7]));
#else /* complex */
        ((npy_longdouble *)data_out + 2*7)[0] =
                                ((npy_longdouble *)data0 + 2*7)[0] +
                                ((npy_longdouble *)data_out + 2*7)[0];
        ((npy_longdouble *)data_out + 2*7)[1] =
                                ((npy_longdouble *)data0 + 2*7)[1] +
                                ((npy_longdouble *)data_out + 2*7)[1];
#endif

        data0 += 8;
        data_out += 8;
    }

    /* Finish off the loop */
    goto finish_after_unrolled_loop;
}

#elif 1000 == 2 && !1

// calculate the multiply and add operation such as dataout = data*scalar+dataout
static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_muladd(npy_clongdouble *data, npy_clongdouble *data_out, npy_longdouble scalar, npy_intp count)
{
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_clongdouble;
    const npyv_clongdouble v_scalar = npyv_setall_clongdouble(scalar);
    #line 306
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_clongdouble b0 = npyv_loada_clongdouble(data + vstep * 0);
            npyv_clongdouble c0 = npyv_loada_clongdouble(data_out + vstep * 0);
            
#line 312
            npyv_clongdouble b1 = npyv_loada_clongdouble(data + vstep * 1);
            npyv_clongdouble c1 = npyv_loada_clongdouble(data_out + vstep * 1);
            
#line 312
            npyv_clongdouble b2 = npyv_loada_clongdouble(data + vstep * 2);
            npyv_clongdouble c2 = npyv_loada_clongdouble(data_out + vstep * 2);
            
#line 312
            npyv_clongdouble b3 = npyv_loada_clongdouble(data + vstep * 3);
            npyv_clongdouble c3 = npyv_loada_clongdouble(data_out + vstep * 3);
            
            #line 318
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(v_scalar, b0, c0);
            
#line 318
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(v_scalar, b1, c1);
            
#line 318
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(v_scalar, b2, c2);
            
#line 318
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_storea_clongdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_storea_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 306
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
            #line 312
            npyv_clongdouble b0 = npyv_load_clongdouble(data + vstep * 0);
            npyv_clongdouble c0 = npyv_load_clongdouble(data_out + vstep * 0);
            
#line 312
            npyv_clongdouble b1 = npyv_load_clongdouble(data + vstep * 1);
            npyv_clongdouble c1 = npyv_load_clongdouble(data_out + vstep * 1);
            
#line 312
            npyv_clongdouble b2 = npyv_load_clongdouble(data + vstep * 2);
            npyv_clongdouble c2 = npyv_load_clongdouble(data_out + vstep * 2);
            
#line 312
            npyv_clongdouble b3 = npyv_load_clongdouble(data + vstep * 3);
            npyv_clongdouble c3 = npyv_load_clongdouble(data_out + vstep * 3);
            
            #line 318
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(v_scalar, b0, c0);
            
#line 318
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(v_scalar, b1, c1);
            
#line 318
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(v_scalar, b2, c2);
            
#line 318
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(v_scalar, b3, c3);
            
            #line 323
            npyv_store_clongdouble(data_out + vstep * 0, abc0);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 1, abc1);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 2, abc2);
            
#line 323
            npyv_store_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data_out, count);
        npyv_store_till_clongdouble(data_out, count, npyv_muladd_clongdouble(a, v_scalar, b));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data += 4, data_out += 4) {
        #line 340
        const npy_longdouble b0 = (data[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 340
        const npy_longdouble b1 = (data[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 340
        const npy_longdouble b2 = (data[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 340
        const npy_longdouble b3 = (data[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 346
        const npy_longdouble abc0 = scalar * b0 + c0;
        
#line 346
        const npy_longdouble abc1 = scalar * b1 + c1;
        
#line 346
        const npy_longdouble abc2 = scalar * b2 + c2;
        
#line 346
        const npy_longdouble abc3 = scalar * b3 + c3;
        
        #line 351
        data_out[0] = (abc0);
        
#line 351
        data_out[1] = (abc1);
        
#line 351
        data_out[2] = (abc2);
        
#line 351
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data, ++data_out) {
        const npy_longdouble b = (*data);
        const npy_longdouble c = (*data_out);
        *data_out = (scalar * b + c);
    }
#endif // NPYV check for npy_clongdouble
}

static void
clongdouble_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_two (%d)\n",
                                                            (int)count);
    // NPYV check for npy_clongdouble
#if 0
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
                        EINSUM_IS_ALIGNED(data_out);
    const int vstep = npyv_nlanes_clongdouble;

    #line 384
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_clongdouble a0 = npyv_loada_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_loada_clongdouble(data1 + vstep * 0);
            npyv_clongdouble c0 = npyv_loada_clongdouble(data_out + vstep * 0);
            
#line 390
            npyv_clongdouble a1 = npyv_loada_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_loada_clongdouble(data1 + vstep * 1);
            npyv_clongdouble c1 = npyv_loada_clongdouble(data_out + vstep * 1);
            
#line 390
            npyv_clongdouble a2 = npyv_loada_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_loada_clongdouble(data1 + vstep * 2);
            npyv_clongdouble c2 = npyv_loada_clongdouble(data_out + vstep * 2);
            
#line 390
            npyv_clongdouble a3 = npyv_loada_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_loada_clongdouble(data1 + vstep * 3);
            npyv_clongdouble c3 = npyv_loada_clongdouble(data_out + vstep * 3);
            
            #line 397
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(a0, b0, c0);
            
#line 397
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(a1, b1, c1);
            
#line 397
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(a2, b2, c2);
            
#line 397
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(a3, b3, c3);
            
            #line 402
            npyv_storea_clongdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_storea_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
#line 384
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
            #line 390
            npyv_clongdouble a0 = npyv_load_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_load_clongdouble(data1 + vstep * 0);
            npyv_clongdouble c0 = npyv_load_clongdouble(data_out + vstep * 0);
            
#line 390
            npyv_clongdouble a1 = npyv_load_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_load_clongdouble(data1 + vstep * 1);
            npyv_clongdouble c1 = npyv_load_clongdouble(data_out + vstep * 1);
            
#line 390
            npyv_clongdouble a2 = npyv_load_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_load_clongdouble(data1 + vstep * 2);
            npyv_clongdouble c2 = npyv_load_clongdouble(data_out + vstep * 2);
            
#line 390
            npyv_clongdouble a3 = npyv_load_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_load_clongdouble(data1 + vstep * 3);
            npyv_clongdouble c3 = npyv_load_clongdouble(data_out + vstep * 3);
            
            #line 397
            npyv_clongdouble abc0 = npyv_muladd_clongdouble(a0, b0, c0);
            
#line 397
            npyv_clongdouble abc1 = npyv_muladd_clongdouble(a1, b1, c1);
            
#line 397
            npyv_clongdouble abc2 = npyv_muladd_clongdouble(a2, b2, c2);
            
#line 397
            npyv_clongdouble abc3 = npyv_muladd_clongdouble(a3, b3, c3);
            
            #line 402
            npyv_store_clongdouble(data_out + vstep * 0, abc0);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 1, abc1);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 2, abc2);
            
#line 402
            npyv_store_clongdouble(data_out + vstep * 3, abc3);
            
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data0, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data1, count);
        npyv_clongdouble c = npyv_load_tillz_clongdouble(data_out, count);
        npyv_store_till_clongdouble(data_out, count, npyv_muladd_clongdouble(a, b, c));
    }
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
        #line 420
        const npy_longdouble a0 = (data0[0]);
        const npy_longdouble b0 = (data1[0]);
        const npy_longdouble c0 = (data_out[0]);
        
#line 420
        const npy_longdouble a1 = (data0[1]);
        const npy_longdouble b1 = (data1[1]);
        const npy_longdouble c1 = (data_out[1]);
        
#line 420
        const npy_longdouble a2 = (data0[2]);
        const npy_longdouble b2 = (data1[2]);
        const npy_longdouble c2 = (data_out[2]);
        
#line 420
        const npy_longdouble a3 = (data0[3]);
        const npy_longdouble b3 = (data1[3]);
        const npy_longdouble c3 = (data_out[3]);
        
        #line 427
        const npy_longdouble abc0 = a0 * b0 + c0;
        
#line 427
        const npy_longdouble abc1 = a1 * b1 + c1;
        
#line 427
        const npy_longdouble abc2 = a2 * b2 + c2;
        
#line 427
        const npy_longdouble abc3 = a3 * b3 + c3;
        
        #line 432
        data_out[0] = (abc0);
        
#line 432
        data_out[1] = (abc1);
        
#line 432
        data_out[2] = (abc2);
        
#line 432
        data_out[3] = (abc3);
        
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1, ++data_out) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        const npy_longdouble c = (*data_out);
        *data_out = (a * b + c);
    }
#endif // NPYV check for npy_clongdouble

}

/* Some extra specializations for the two operand case */
static void
clongdouble_sum_of_products_stride0_contig_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value0 = (*(npy_clongdouble *)dataptr[0]);
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_stride0_contig_outcontig_two (%d)\n",
                                                    (int)count);
    clongdouble_sum_of_products_muladd(data1, data_out, value0, count);
    
}

static void
clongdouble_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_longdouble value1 = (*(npy_clongdouble *)dataptr[1]);
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[2];

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_stride0_outcontig_two (%d)\n",
                                                    (int)count);
    clongdouble_sum_of_products_muladd(data0, data_out, value1, count);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_longdouble accum = 0;

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_contig_outstride0_two (%d)\n",
                                                    (int)count);
#if 0 // NPYV check for npy_clongdouble
    /* Use aligned instructions if possible */
    const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
    const int vstep = npyv_nlanes_clongdouble;
    npyv_clongdouble v_accum = npyv_zero_clongdouble();

    #line 495
    if(is_aligned) {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_clongdouble a0 = npyv_loada_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_loada_clongdouble(data1 + vstep * 0);
            
#line 501
            npyv_clongdouble a1 = npyv_loada_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_loada_clongdouble(data1 + vstep * 1);
            
#line 501
            npyv_clongdouble a2 = npyv_loada_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_loada_clongdouble(data1 + vstep * 2);
            
#line 501
            npyv_clongdouble a3 = npyv_loada_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_loada_clongdouble(data1 + vstep * 3);
            
            npyv_clongdouble ab3 = npyv_muladd_clongdouble(a3, b3, v_accum);
            npyv_clongdouble ab2 = npyv_muladd_clongdouble(a2, b2, ab3);
            npyv_clongdouble ab1 = npyv_muladd_clongdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_clongdouble(a0, b0, ab1);
        }
    }
    
#line 495
    else {
        const npy_intp vstepx4 = vstep * 4;
        for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
            #line 501
            npyv_clongdouble a0 = npyv_load_clongdouble(data0 + vstep * 0);
            npyv_clongdouble b0 = npyv_load_clongdouble(data1 + vstep * 0);
            
#line 501
            npyv_clongdouble a1 = npyv_load_clongdouble(data0 + vstep * 1);
            npyv_clongdouble b1 = npyv_load_clongdouble(data1 + vstep * 1);
            
#line 501
            npyv_clongdouble a2 = npyv_load_clongdouble(data0 + vstep * 2);
            npyv_clongdouble b2 = npyv_load_clongdouble(data1 + vstep * 2);
            
#line 501
            npyv_clongdouble a3 = npyv_load_clongdouble(data0 + vstep * 3);
            npyv_clongdouble b3 = npyv_load_clongdouble(data1 + vstep * 3);
            
            npyv_clongdouble ab3 = npyv_muladd_clongdouble(a3, b3, v_accum);
            npyv_clongdouble ab2 = npyv_muladd_clongdouble(a2, b2, ab3);
            npyv_clongdouble ab1 = npyv_muladd_clongdouble(a1, b1, ab2);
                   v_accum = npyv_muladd_clongdouble(a0, b0, ab1);
        }
    }
    
    for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
        npyv_clongdouble a = npyv_load_tillz_clongdouble(data0, count);
        npyv_clongdouble b = npyv_load_tillz_clongdouble(data1, count);
        v_accum = npyv_muladd_clongdouble(a, b, v_accum);
    }
    accum = npyv_sum_clongdouble(v_accum);
    npyv_cleanup();
#else
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
        #line 524
        const npy_longdouble ab0 = (data0[0]) * (data1[0]);
        
#line 524
        const npy_longdouble ab1 = (data0[1]) * (data1[1]);
        
#line 524
        const npy_longdouble ab2 = (data0[2]) * (data1[2]);
        
#line 524
        const npy_longdouble ab3 = (data0[3]) * (data1[3]);
        
        accum += ab0 + ab1 + ab2 + ab3;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, ++data0, ++data1) {
        const npy_longdouble a = (*data0);
        const npy_longdouble b = (*data1);
        accum += a * b;
    }
#endif // NPYV check for npy_clongdouble
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + accum);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_longdouble value0 = (*(npy_clongdouble *)dataptr[0]);
    npy_longdouble accum = clongdouble_sum_of_arr(data1, count);
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + value0 * accum);
}

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_longdouble value1 = (*(npy_clongdouble *)dataptr[1]);
    npy_longdouble accum = clongdouble_sum_of_arr(data0, count);
    *(npy_clongdouble *)dataptr[2] = ((*(npy_clongdouble *)dataptr[2]) + value1 * accum);
}

#elif 1000 == 3 && !1

static void
clongdouble_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    npy_clongdouble *data0 = (npy_clongdouble *)dataptr[0];
    npy_clongdouble *data1 = (npy_clongdouble *)dataptr[1];
    npy_clongdouble *data2 = (npy_clongdouble *)dataptr[2];
    npy_clongdouble *data_out = (npy_clongdouble *)dataptr[3];

    /* Unroll the loop by 8 */
    while (count >= 8) {
        count -= 8;

#line 576
        data_out[0] = ((data0[0]) *
                             (data1[0]) *
                             (data2[0]) +
                             (data_out[0]));

#line 576
        data_out[1] = ((data0[1]) *
                             (data1[1]) *
                             (data2[1]) +
                             (data_out[1]));

#line 576
        data_out[2] = ((data0[2]) *
                             (data1[2]) *
                             (data2[2]) +
                             (data_out[2]));

#line 576
        data_out[3] = ((data0[3]) *
                             (data1[3]) *
                             (data2[3]) +
                             (data_out[3]));

#line 576
        data_out[4] = ((data0[4]) *
                             (data1[4]) *
                             (data2[4]) +
                             (data_out[4]));

#line 576
        data_out[5] = ((data0[5]) *
                             (data1[5]) *
                             (data2[5]) +
                             (data_out[5]));

#line 576
        data_out[6] = ((data0[6]) *
                             (data1[6]) *
                             (data2[6]) +
                             (data_out[6]));

#line 576
        data_out[7] = ((data0[7]) *
                             (data1[7]) *
                             (data2[7]) +
                             (data_out[7]));

        data0 += 8;
        data1 += 8;
        data2 += 8;
        data_out += 8;
    }

    /* Finish off the loop */

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[0] = ((data0[0]) *
                         (data1[0]) *
                         (data2[0]) +
                         (data_out[0]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[1] = ((data0[1]) *
                         (data1[1]) *
                         (data2[1]) +
                         (data_out[1]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[2] = ((data0[2]) *
                         (data1[2]) *
                         (data2[2]) +
                         (data_out[2]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[3] = ((data0[3]) *
                         (data1[3]) *
                         (data2[3]) +
                         (data_out[3]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[4] = ((data0[4]) *
                         (data1[4]) *
                         (data2[4]) +
                         (data_out[4]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[5] = ((data0[5]) *
                         (data1[5]) *
                         (data2[5]) +
                         (data_out[5]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[6] = ((data0[6]) *
                         (data1[6]) *
                         (data2[6]) +
                         (data_out[6]));

#line 592
    if (count-- == 0) {
        return;
    }
    data_out[7] = ((data0[7]) *
                         (data1[7]) *
                         (data2[7]) +
                         (data_out[7]));

}

#else /* 1000 > 3 || @complex */

static void
clongdouble_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        *(npy_clongdouble *)dataptr[nop] = (temp +
                                           (*(npy_clongdouble *)dataptr[i]));
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_clongdouble);
        }
#else /* complex */
#  if 1000 <= 3
#    define _SUMPROD_NOP 1000
#  else
#    define _SUMPROD_NOP nop
#  endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0] = re +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[0];
        ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1] = im +
                                     ((npy_longdouble *)dataptr[_SUMPROD_NOP])[1];

        for (i = 0; i <= _SUMPROD_NOP; ++i) {
            dataptr[i] += sizeof(npy_clongdouble);
        }
#  undef _SUMPROD_NOP
#endif
    }
}

#endif /* functions for various 1000 */

#if 1000 == 1

static NPY_GCC_OPT_3 void
clongdouble_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !1
    npy_clongdouble *data = (npy_clongdouble *)dataptr[0];
    npy_longdouble accum = clongdouble_sum_of_arr(data, count);
    *((npy_clongdouble *)dataptr[1]) = (accum + (*((npy_clongdouble *)dataptr[1])));
#else
    npy_longdouble accum_re = 0, accum_im = 0;
    npy_longdouble *data0 = (npy_longdouble *)dataptr[0];
#ifndef NPY_DISABLE_OPTIMIZATION
    for (; count > 4; count -= 4, data0 += 4*2) {
        const npy_longdouble re01 = data0[0] + data0[2];
        const npy_longdouble re23 = data0[4] + data0[6];
        const npy_longdouble im13 = data0[1] + data0[3];
        const npy_longdouble im57 = data0[5] + data0[7];
        accum_re += re01 + re23;
        accum_im += im13 + im57;
    }
#endif // !NPY_DISABLE_OPTIMIZATION
    for (; count > 0; --count, data0 += 2) {
        accum_re += data0[0];
        accum_im += data0[1];
    }
    ((npy_longdouble *)dataptr[1])[0] += accum_re;
    ((npy_longdouble *)dataptr[1])[1] += accum_im;
#endif // !1
}

#endif /* 1000 == 1 */

static void
clongdouble_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if 1
    npy_longdouble accum_re = 0, accum_im = 0;
#else
    npy_longdouble accum = 0;
#endif

#if (1000 == 1) || (1000 <= 3 && !1)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3) && !1
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3) && !1
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    NPY_EINSUM_DBG_PRINT1("clongdouble_sum_of_products_outstride0_any (%d)\n",
                                                    (int)count);

    while (count--) {
#if !1
#  if 1000 == 1
        accum += (*(npy_clongdouble *)data0);
        data0 += stride0;
#  elif 1000 == 2
        accum += (*(npy_clongdouble *)data0) *
                 (*(npy_clongdouble *)data1);
        data0 += stride0;
        data1 += stride1;
#  elif 1000 == 3
        accum += (*(npy_clongdouble *)data0) *
                 (*(npy_clongdouble *)data1) *
                 (*(npy_clongdouble *)data2);
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#  else
        npy_longdouble temp = (*(npy_clongdouble *)dataptr[0]);
        int i;
        for (i = 1; i < nop; ++i) {
            temp *= (*(npy_clongdouble *)dataptr[i]);
        }
        accum += temp;
        for (i = 0; i < nop; ++i) {
            dataptr[i] += strides[i];
        }
#  endif
#else /* complex */
#  if 1000 == 1
        accum_re += ((npy_longdouble *)data0)[0];
        accum_im += ((npy_longdouble *)data0)[1];
        data0 += stride0;
#  else
#    if 1000 <= 3
#define _SUMPROD_NOP 1000
#    else
#define _SUMPROD_NOP nop
#    endif
        npy_longdouble re, im, tmp;
        int i;
        re = ((npy_longdouble *)dataptr[0])[0];
        im = ((npy_longdouble *)dataptr[0])[1];
        for (i = 1; i < _SUMPROD_NOP; ++i) {
            tmp = re * ((npy_longdouble *)dataptr[i])[0] -
                  im * ((npy_longdouble *)dataptr[i])[1];
            im = re * ((npy_longdouble *)dataptr[i])[1] +
                 im * ((npy_longdouble *)dataptr[i])[0];
            re = tmp;
        }
        accum_re += re;
        accum_im += im;
        for (i = 0; i < _SUMPROD_NOP; ++i) {
            dataptr[i] += strides[i];
        }
#undef _SUMPROD_NOP
#  endif
#endif
    }

#if 1
#  if 1000 <= 3
    ((npy_longdouble *)dataptr[1000])[0] += accum_re;
    ((npy_longdouble *)dataptr[1000])[1] += accum_im;
#  else
    ((npy_longdouble *)dataptr[nop])[0] += accum_re;
    ((npy_longdouble *)dataptr[nop])[1] += accum_im;
#  endif
#else
#  if 1000 <= 3
    *((npy_clongdouble *)dataptr[1000]) = (accum +
                                    (*((npy_clongdouble *)dataptr[1000])));
#  else
    *((npy_clongdouble *)dataptr[nop]) = (accum +
                                    (*((npy_clongdouble *)dataptr[nop])));
#  endif
#endif

}






/* Do OR of ANDs for the boolean type */

#line 807

static void
bool_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 <= 3)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3)
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3)
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1 <= 3)
    char *data_out = dataptr[1];
    npy_intp stride_out = strides[1];
#endif

    while (count--) {
#if 1 == 1
        *(npy_bool *)data_out = *(npy_bool *)data0 ||
                                  *(npy_bool *)data_out;
        data0 += stride0;
        data_out += stride_out;
#elif 1 == 2
        *(npy_bool *)data_out = (*(npy_bool *)data0 &&
                                   *(npy_bool *)data1) ||
                                   *(npy_bool *)data_out;
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#elif 1 == 3
        *(npy_bool *)data_out = (*(npy_bool *)data0 &&
                                   *(npy_bool *)data1 &&
                                   *(npy_bool *)data2) ||
                                   *(npy_bool *)data_out;
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        *(npy_bool *)dataptr[nop] = temp || *(npy_bool *)dataptr[i];
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#endif
    }
}

static void
bool_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1 <= 3)
    char *data0 = dataptr[0];
#endif
#if (1 == 2 || 1 == 3)
    char *data1 = dataptr[1];
#endif
#if (1 == 3)
    char *data2 = dataptr[2];
#endif
#if (1 <= 3)
    char *data_out = dataptr[1];
#endif

#if (1 <= 3)
/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 889
        case 6+1:
#  if 1 == 1
            ((npy_bool *)data_out)[6] = ((npy_bool *)data0)[6] ||
                                            ((npy_bool *)data_out)[6];
#  elif 1 == 2
            ((npy_bool *)data_out)[6] =
                            (((npy_bool *)data0)[6] &&
                             ((npy_bool *)data1)[6]) ||
                                ((npy_bool *)data_out)[6];
#  elif 1 == 3
            ((npy_bool *)data_out)[6] =
                           (((npy_bool *)data0)[6] &&
                            ((npy_bool *)data1)[6] &&
                            ((npy_bool *)data2)[6]) ||
                                ((npy_bool *)data_out)[6];
#  endif

#line 889
        case 5+1:
#  if 1 == 1
            ((npy_bool *)data_out)[5] = ((npy_bool *)data0)[5] ||
                                            ((npy_bool *)data_out)[5];
#  elif 1 == 2
            ((npy_bool *)data_out)[5] =
                            (((npy_bool *)data0)[5] &&
                             ((npy_bool *)data1)[5]) ||
                                ((npy_bool *)data_out)[5];
#  elif 1 == 3
            ((npy_bool *)data_out)[5] =
                           (((npy_bool *)data0)[5] &&
                            ((npy_bool *)data1)[5] &&
                            ((npy_bool *)data2)[5]) ||
                                ((npy_bool *)data_out)[5];
#  endif

#line 889
        case 4+1:
#  if 1 == 1
            ((npy_bool *)data_out)[4] = ((npy_bool *)data0)[4] ||
                                            ((npy_bool *)data_out)[4];
#  elif 1 == 2
            ((npy_bool *)data_out)[4] =
                            (((npy_bool *)data0)[4] &&
                             ((npy_bool *)data1)[4]) ||
                                ((npy_bool *)data_out)[4];
#  elif 1 == 3
            ((npy_bool *)data_out)[4] =
                           (((npy_bool *)data0)[4] &&
                            ((npy_bool *)data1)[4] &&
                            ((npy_bool *)data2)[4]) ||
                                ((npy_bool *)data_out)[4];
#  endif

#line 889
        case 3+1:
#  if 1 == 1
            ((npy_bool *)data_out)[3] = ((npy_bool *)data0)[3] ||
                                            ((npy_bool *)data_out)[3];
#  elif 1 == 2
            ((npy_bool *)data_out)[3] =
                            (((npy_bool *)data0)[3] &&
                             ((npy_bool *)data1)[3]) ||
                                ((npy_bool *)data_out)[3];
#  elif 1 == 3
            ((npy_bool *)data_out)[3] =
                           (((npy_bool *)data0)[3] &&
                            ((npy_bool *)data1)[3] &&
                            ((npy_bool *)data2)[3]) ||
                                ((npy_bool *)data_out)[3];
#  endif

#line 889
        case 2+1:
#  if 1 == 1
            ((npy_bool *)data_out)[2] = ((npy_bool *)data0)[2] ||
                                            ((npy_bool *)data_out)[2];
#  elif 1 == 2
            ((npy_bool *)data_out)[2] =
                            (((npy_bool *)data0)[2] &&
                             ((npy_bool *)data1)[2]) ||
                                ((npy_bool *)data_out)[2];
#  elif 1 == 3
            ((npy_bool *)data_out)[2] =
                           (((npy_bool *)data0)[2] &&
                            ((npy_bool *)data1)[2] &&
                            ((npy_bool *)data2)[2]) ||
                                ((npy_bool *)data_out)[2];
#  endif

#line 889
        case 1+1:
#  if 1 == 1
            ((npy_bool *)data_out)[1] = ((npy_bool *)data0)[1] ||
                                            ((npy_bool *)data_out)[1];
#  elif 1 == 2
            ((npy_bool *)data_out)[1] =
                            (((npy_bool *)data0)[1] &&
                             ((npy_bool *)data1)[1]) ||
                                ((npy_bool *)data_out)[1];
#  elif 1 == 3
            ((npy_bool *)data_out)[1] =
                           (((npy_bool *)data0)[1] &&
                            ((npy_bool *)data1)[1] &&
                            ((npy_bool *)data2)[1]) ||
                                ((npy_bool *)data_out)[1];
#  endif

#line 889
        case 0+1:
#  if 1 == 1
            ((npy_bool *)data_out)[0] = ((npy_bool *)data0)[0] ||
                                            ((npy_bool *)data_out)[0];
#  elif 1 == 2
            ((npy_bool *)data_out)[0] =
                            (((npy_bool *)data0)[0] &&
                             ((npy_bool *)data1)[0]) ||
                                ((npy_bool *)data_out)[0];
#  elif 1 == 3
            ((npy_bool *)data_out)[0] =
                           (((npy_bool *)data0)[0] &&
                            ((npy_bool *)data1)[0] &&
                            ((npy_bool *)data2)[0]) ||
                                ((npy_bool *)data_out)[0];
#  endif

        case 0:
            return;
    }
#endif

/* Unroll the loop by 8 for fixed-size nop */
#if (1 <= 3)
    while (count >= 8) {
        count -= 8;
#else
    while (count--) {
#endif

#  if 1 == 1
#line 923
        *((npy_bool *)data_out + 0) = (*((npy_bool *)data0 + 0)) ||
                                        (*((npy_bool *)data_out + 0));

#line 923
        *((npy_bool *)data_out + 1) = (*((npy_bool *)data0 + 1)) ||
                                        (*((npy_bool *)data_out + 1));

#line 923
        *((npy_bool *)data_out + 2) = (*((npy_bool *)data0 + 2)) ||
                                        (*((npy_bool *)data_out + 2));

#line 923
        *((npy_bool *)data_out + 3) = (*((npy_bool *)data0 + 3)) ||
                                        (*((npy_bool *)data_out + 3));

#line 923
        *((npy_bool *)data_out + 4) = (*((npy_bool *)data0 + 4)) ||
                                        (*((npy_bool *)data_out + 4));

#line 923
        *((npy_bool *)data_out + 5) = (*((npy_bool *)data0 + 5)) ||
                                        (*((npy_bool *)data_out + 5));

#line 923
        *((npy_bool *)data_out + 6) = (*((npy_bool *)data0 + 6)) ||
                                        (*((npy_bool *)data_out + 6));

#line 923
        *((npy_bool *)data_out + 7) = (*((npy_bool *)data0 + 7)) ||
                                        (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  elif 1 == 2
#line 932
        *((npy_bool *)data_out + 0) =
                        ((*((npy_bool *)data0 + 0)) &&
                         (*((npy_bool *)data1 + 0))) ||
                            (*((npy_bool *)data_out + 0));

#line 932
        *((npy_bool *)data_out + 1) =
                        ((*((npy_bool *)data0 + 1)) &&
                         (*((npy_bool *)data1 + 1))) ||
                            (*((npy_bool *)data_out + 1));

#line 932
        *((npy_bool *)data_out + 2) =
                        ((*((npy_bool *)data0 + 2)) &&
                         (*((npy_bool *)data1 + 2))) ||
                            (*((npy_bool *)data_out + 2));

#line 932
        *((npy_bool *)data_out + 3) =
                        ((*((npy_bool *)data0 + 3)) &&
                         (*((npy_bool *)data1 + 3))) ||
                            (*((npy_bool *)data_out + 3));

#line 932
        *((npy_bool *)data_out + 4) =
                        ((*((npy_bool *)data0 + 4)) &&
                         (*((npy_bool *)data1 + 4))) ||
                            (*((npy_bool *)data_out + 4));

#line 932
        *((npy_bool *)data_out + 5) =
                        ((*((npy_bool *)data0 + 5)) &&
                         (*((npy_bool *)data1 + 5))) ||
                            (*((npy_bool *)data_out + 5));

#line 932
        *((npy_bool *)data_out + 6) =
                        ((*((npy_bool *)data0 + 6)) &&
                         (*((npy_bool *)data1 + 6))) ||
                            (*((npy_bool *)data_out + 6));

#line 932
        *((npy_bool *)data_out + 7) =
                        ((*((npy_bool *)data0 + 7)) &&
                         (*((npy_bool *)data1 + 7))) ||
                            (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data1 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  elif 1 == 3
#line 944
        *((npy_bool *)data_out + 0) =
                       ((*((npy_bool *)data0 + 0)) &&
                        (*((npy_bool *)data1 + 0)) &&
                        (*((npy_bool *)data2 + 0))) ||
                            (*((npy_bool *)data_out + 0));

#line 944
        *((npy_bool *)data_out + 1) =
                       ((*((npy_bool *)data0 + 1)) &&
                        (*((npy_bool *)data1 + 1)) &&
                        (*((npy_bool *)data2 + 1))) ||
                            (*((npy_bool *)data_out + 1));

#line 944
        *((npy_bool *)data_out + 2) =
                       ((*((npy_bool *)data0 + 2)) &&
                        (*((npy_bool *)data1 + 2)) &&
                        (*((npy_bool *)data2 + 2))) ||
                            (*((npy_bool *)data_out + 2));

#line 944
        *((npy_bool *)data_out + 3) =
                       ((*((npy_bool *)data0 + 3)) &&
                        (*((npy_bool *)data1 + 3)) &&
                        (*((npy_bool *)data2 + 3))) ||
                            (*((npy_bool *)data_out + 3));

#line 944
        *((npy_bool *)data_out + 4) =
                       ((*((npy_bool *)data0 + 4)) &&
                        (*((npy_bool *)data1 + 4)) &&
                        (*((npy_bool *)data2 + 4))) ||
                            (*((npy_bool *)data_out + 4));

#line 944
        *((npy_bool *)data_out + 5) =
                       ((*((npy_bool *)data0 + 5)) &&
                        (*((npy_bool *)data1 + 5)) &&
                        (*((npy_bool *)data2 + 5))) ||
                            (*((npy_bool *)data_out + 5));

#line 944
        *((npy_bool *)data_out + 6) =
                       ((*((npy_bool *)data0 + 6)) &&
                        (*((npy_bool *)data1 + 6)) &&
                        (*((npy_bool *)data2 + 6))) ||
                            (*((npy_bool *)data_out + 6));

#line 944
        *((npy_bool *)data_out + 7) =
                       ((*((npy_bool *)data0 + 7)) &&
                        (*((npy_bool *)data1 + 7)) &&
                        (*((npy_bool *)data2 + 7))) ||
                            (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data1 += 8*sizeof(npy_bool);
        data2 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        *(npy_bool *)dataptr[nop] = temp || *(npy_bool *)dataptr[i];
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_bool);
        }
#  endif
    }

    /* If the loop was unrolled, we need to finish it off */
#if (1 <= 3)
    goto finish_after_unrolled_loop;
#endif
}

static void
bool_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    npy_bool accum = 0;

#if (1 <= 3)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1 == 2 || 1 == 3)
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1 == 3)
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    while (count--) {
#if 1 == 1
        accum = *(npy_bool *)data0 || accum;
        data0 += stride0;
#elif 1 == 2
        accum = (*(npy_bool *)data0 && *(npy_bool *)data1) || accum;
        data0 += stride0;
        data1 += stride1;
#elif 1 == 3
        accum = (*(npy_bool *)data0 &&
                 *(npy_bool *)data1 &&
                 *(npy_bool *)data2) || accum;
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        accum = temp || accum;
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#endif
    }

#  if 1 <= 3
    *((npy_bool *)dataptr[1]) = accum || *((npy_bool *)dataptr[1]);
#  else
    *((npy_bool *)dataptr[nop]) = accum || *((npy_bool *)dataptr[nop]);
#  endif
}


#line 807

static void
bool_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 <= 3)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3)
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3)
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (2 <= 3)
    char *data_out = dataptr[2];
    npy_intp stride_out = strides[2];
#endif

    while (count--) {
#if 2 == 1
        *(npy_bool *)data_out = *(npy_bool *)data0 ||
                                  *(npy_bool *)data_out;
        data0 += stride0;
        data_out += stride_out;
#elif 2 == 2
        *(npy_bool *)data_out = (*(npy_bool *)data0 &&
                                   *(npy_bool *)data1) ||
                                   *(npy_bool *)data_out;
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#elif 2 == 3
        *(npy_bool *)data_out = (*(npy_bool *)data0 &&
                                   *(npy_bool *)data1 &&
                                   *(npy_bool *)data2) ||
                                   *(npy_bool *)data_out;
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        *(npy_bool *)dataptr[nop] = temp || *(npy_bool *)dataptr[i];
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#endif
    }
}

static void
bool_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (2 <= 3)
    char *data0 = dataptr[0];
#endif
#if (2 == 2 || 2 == 3)
    char *data1 = dataptr[1];
#endif
#if (2 == 3)
    char *data2 = dataptr[2];
#endif
#if (2 <= 3)
    char *data_out = dataptr[2];
#endif

#if (2 <= 3)
/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 889
        case 6+1:
#  if 2 == 1
            ((npy_bool *)data_out)[6] = ((npy_bool *)data0)[6] ||
                                            ((npy_bool *)data_out)[6];
#  elif 2 == 2
            ((npy_bool *)data_out)[6] =
                            (((npy_bool *)data0)[6] &&
                             ((npy_bool *)data1)[6]) ||
                                ((npy_bool *)data_out)[6];
#  elif 2 == 3
            ((npy_bool *)data_out)[6] =
                           (((npy_bool *)data0)[6] &&
                            ((npy_bool *)data1)[6] &&
                            ((npy_bool *)data2)[6]) ||
                                ((npy_bool *)data_out)[6];
#  endif

#line 889
        case 5+1:
#  if 2 == 1
            ((npy_bool *)data_out)[5] = ((npy_bool *)data0)[5] ||
                                            ((npy_bool *)data_out)[5];
#  elif 2 == 2
            ((npy_bool *)data_out)[5] =
                            (((npy_bool *)data0)[5] &&
                             ((npy_bool *)data1)[5]) ||
                                ((npy_bool *)data_out)[5];
#  elif 2 == 3
            ((npy_bool *)data_out)[5] =
                           (((npy_bool *)data0)[5] &&
                            ((npy_bool *)data1)[5] &&
                            ((npy_bool *)data2)[5]) ||
                                ((npy_bool *)data_out)[5];
#  endif

#line 889
        case 4+1:
#  if 2 == 1
            ((npy_bool *)data_out)[4] = ((npy_bool *)data0)[4] ||
                                            ((npy_bool *)data_out)[4];
#  elif 2 == 2
            ((npy_bool *)data_out)[4] =
                            (((npy_bool *)data0)[4] &&
                             ((npy_bool *)data1)[4]) ||
                                ((npy_bool *)data_out)[4];
#  elif 2 == 3
            ((npy_bool *)data_out)[4] =
                           (((npy_bool *)data0)[4] &&
                            ((npy_bool *)data1)[4] &&
                            ((npy_bool *)data2)[4]) ||
                                ((npy_bool *)data_out)[4];
#  endif

#line 889
        case 3+1:
#  if 2 == 1
            ((npy_bool *)data_out)[3] = ((npy_bool *)data0)[3] ||
                                            ((npy_bool *)data_out)[3];
#  elif 2 == 2
            ((npy_bool *)data_out)[3] =
                            (((npy_bool *)data0)[3] &&
                             ((npy_bool *)data1)[3]) ||
                                ((npy_bool *)data_out)[3];
#  elif 2 == 3
            ((npy_bool *)data_out)[3] =
                           (((npy_bool *)data0)[3] &&
                            ((npy_bool *)data1)[3] &&
                            ((npy_bool *)data2)[3]) ||
                                ((npy_bool *)data_out)[3];
#  endif

#line 889
        case 2+1:
#  if 2 == 1
            ((npy_bool *)data_out)[2] = ((npy_bool *)data0)[2] ||
                                            ((npy_bool *)data_out)[2];
#  elif 2 == 2
            ((npy_bool *)data_out)[2] =
                            (((npy_bool *)data0)[2] &&
                             ((npy_bool *)data1)[2]) ||
                                ((npy_bool *)data_out)[2];
#  elif 2 == 3
            ((npy_bool *)data_out)[2] =
                           (((npy_bool *)data0)[2] &&
                            ((npy_bool *)data1)[2] &&
                            ((npy_bool *)data2)[2]) ||
                                ((npy_bool *)data_out)[2];
#  endif

#line 889
        case 1+1:
#  if 2 == 1
            ((npy_bool *)data_out)[1] = ((npy_bool *)data0)[1] ||
                                            ((npy_bool *)data_out)[1];
#  elif 2 == 2
            ((npy_bool *)data_out)[1] =
                            (((npy_bool *)data0)[1] &&
                             ((npy_bool *)data1)[1]) ||
                                ((npy_bool *)data_out)[1];
#  elif 2 == 3
            ((npy_bool *)data_out)[1] =
                           (((npy_bool *)data0)[1] &&
                            ((npy_bool *)data1)[1] &&
                            ((npy_bool *)data2)[1]) ||
                                ((npy_bool *)data_out)[1];
#  endif

#line 889
        case 0+1:
#  if 2 == 1
            ((npy_bool *)data_out)[0] = ((npy_bool *)data0)[0] ||
                                            ((npy_bool *)data_out)[0];
#  elif 2 == 2
            ((npy_bool *)data_out)[0] =
                            (((npy_bool *)data0)[0] &&
                             ((npy_bool *)data1)[0]) ||
                                ((npy_bool *)data_out)[0];
#  elif 2 == 3
            ((npy_bool *)data_out)[0] =
                           (((npy_bool *)data0)[0] &&
                            ((npy_bool *)data1)[0] &&
                            ((npy_bool *)data2)[0]) ||
                                ((npy_bool *)data_out)[0];
#  endif

        case 0:
            return;
    }
#endif

/* Unroll the loop by 8 for fixed-size nop */
#if (2 <= 3)
    while (count >= 8) {
        count -= 8;
#else
    while (count--) {
#endif

#  if 2 == 1
#line 923
        *((npy_bool *)data_out + 0) = (*((npy_bool *)data0 + 0)) ||
                                        (*((npy_bool *)data_out + 0));

#line 923
        *((npy_bool *)data_out + 1) = (*((npy_bool *)data0 + 1)) ||
                                        (*((npy_bool *)data_out + 1));

#line 923
        *((npy_bool *)data_out + 2) = (*((npy_bool *)data0 + 2)) ||
                                        (*((npy_bool *)data_out + 2));

#line 923
        *((npy_bool *)data_out + 3) = (*((npy_bool *)data0 + 3)) ||
                                        (*((npy_bool *)data_out + 3));

#line 923
        *((npy_bool *)data_out + 4) = (*((npy_bool *)data0 + 4)) ||
                                        (*((npy_bool *)data_out + 4));

#line 923
        *((npy_bool *)data_out + 5) = (*((npy_bool *)data0 + 5)) ||
                                        (*((npy_bool *)data_out + 5));

#line 923
        *((npy_bool *)data_out + 6) = (*((npy_bool *)data0 + 6)) ||
                                        (*((npy_bool *)data_out + 6));

#line 923
        *((npy_bool *)data_out + 7) = (*((npy_bool *)data0 + 7)) ||
                                        (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  elif 2 == 2
#line 932
        *((npy_bool *)data_out + 0) =
                        ((*((npy_bool *)data0 + 0)) &&
                         (*((npy_bool *)data1 + 0))) ||
                            (*((npy_bool *)data_out + 0));

#line 932
        *((npy_bool *)data_out + 1) =
                        ((*((npy_bool *)data0 + 1)) &&
                         (*((npy_bool *)data1 + 1))) ||
                            (*((npy_bool *)data_out + 1));

#line 932
        *((npy_bool *)data_out + 2) =
                        ((*((npy_bool *)data0 + 2)) &&
                         (*((npy_bool *)data1 + 2))) ||
                            (*((npy_bool *)data_out + 2));

#line 932
        *((npy_bool *)data_out + 3) =
                        ((*((npy_bool *)data0 + 3)) &&
                         (*((npy_bool *)data1 + 3))) ||
                            (*((npy_bool *)data_out + 3));

#line 932
        *((npy_bool *)data_out + 4) =
                        ((*((npy_bool *)data0 + 4)) &&
                         (*((npy_bool *)data1 + 4))) ||
                            (*((npy_bool *)data_out + 4));

#line 932
        *((npy_bool *)data_out + 5) =
                        ((*((npy_bool *)data0 + 5)) &&
                         (*((npy_bool *)data1 + 5))) ||
                            (*((npy_bool *)data_out + 5));

#line 932
        *((npy_bool *)data_out + 6) =
                        ((*((npy_bool *)data0 + 6)) &&
                         (*((npy_bool *)data1 + 6))) ||
                            (*((npy_bool *)data_out + 6));

#line 932
        *((npy_bool *)data_out + 7) =
                        ((*((npy_bool *)data0 + 7)) &&
                         (*((npy_bool *)data1 + 7))) ||
                            (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data1 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  elif 2 == 3
#line 944
        *((npy_bool *)data_out + 0) =
                       ((*((npy_bool *)data0 + 0)) &&
                        (*((npy_bool *)data1 + 0)) &&
                        (*((npy_bool *)data2 + 0))) ||
                            (*((npy_bool *)data_out + 0));

#line 944
        *((npy_bool *)data_out + 1) =
                       ((*((npy_bool *)data0 + 1)) &&
                        (*((npy_bool *)data1 + 1)) &&
                        (*((npy_bool *)data2 + 1))) ||
                            (*((npy_bool *)data_out + 1));

#line 944
        *((npy_bool *)data_out + 2) =
                       ((*((npy_bool *)data0 + 2)) &&
                        (*((npy_bool *)data1 + 2)) &&
                        (*((npy_bool *)data2 + 2))) ||
                            (*((npy_bool *)data_out + 2));

#line 944
        *((npy_bool *)data_out + 3) =
                       ((*((npy_bool *)data0 + 3)) &&
                        (*((npy_bool *)data1 + 3)) &&
                        (*((npy_bool *)data2 + 3))) ||
                            (*((npy_bool *)data_out + 3));

#line 944
        *((npy_bool *)data_out + 4) =
                       ((*((npy_bool *)data0 + 4)) &&
                        (*((npy_bool *)data1 + 4)) &&
                        (*((npy_bool *)data2 + 4))) ||
                            (*((npy_bool *)data_out + 4));

#line 944
        *((npy_bool *)data_out + 5) =
                       ((*((npy_bool *)data0 + 5)) &&
                        (*((npy_bool *)data1 + 5)) &&
                        (*((npy_bool *)data2 + 5))) ||
                            (*((npy_bool *)data_out + 5));

#line 944
        *((npy_bool *)data_out + 6) =
                       ((*((npy_bool *)data0 + 6)) &&
                        (*((npy_bool *)data1 + 6)) &&
                        (*((npy_bool *)data2 + 6))) ||
                            (*((npy_bool *)data_out + 6));

#line 944
        *((npy_bool *)data_out + 7) =
                       ((*((npy_bool *)data0 + 7)) &&
                        (*((npy_bool *)data1 + 7)) &&
                        (*((npy_bool *)data2 + 7))) ||
                            (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data1 += 8*sizeof(npy_bool);
        data2 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        *(npy_bool *)dataptr[nop] = temp || *(npy_bool *)dataptr[i];
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_bool);
        }
#  endif
    }

    /* If the loop was unrolled, we need to finish it off */
#if (2 <= 3)
    goto finish_after_unrolled_loop;
#endif
}

static void
bool_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    npy_bool accum = 0;

#if (2 <= 3)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (2 == 2 || 2 == 3)
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (2 == 3)
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    while (count--) {
#if 2 == 1
        accum = *(npy_bool *)data0 || accum;
        data0 += stride0;
#elif 2 == 2
        accum = (*(npy_bool *)data0 && *(npy_bool *)data1) || accum;
        data0 += stride0;
        data1 += stride1;
#elif 2 == 3
        accum = (*(npy_bool *)data0 &&
                 *(npy_bool *)data1 &&
                 *(npy_bool *)data2) || accum;
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        accum = temp || accum;
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#endif
    }

#  if 2 <= 3
    *((npy_bool *)dataptr[2]) = accum || *((npy_bool *)dataptr[2]);
#  else
    *((npy_bool *)dataptr[nop]) = accum || *((npy_bool *)dataptr[nop]);
#  endif
}


#line 807

static void
bool_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 <= 3)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3)
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3)
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (3 <= 3)
    char *data_out = dataptr[3];
    npy_intp stride_out = strides[3];
#endif

    while (count--) {
#if 3 == 1
        *(npy_bool *)data_out = *(npy_bool *)data0 ||
                                  *(npy_bool *)data_out;
        data0 += stride0;
        data_out += stride_out;
#elif 3 == 2
        *(npy_bool *)data_out = (*(npy_bool *)data0 &&
                                   *(npy_bool *)data1) ||
                                   *(npy_bool *)data_out;
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#elif 3 == 3
        *(npy_bool *)data_out = (*(npy_bool *)data0 &&
                                   *(npy_bool *)data1 &&
                                   *(npy_bool *)data2) ||
                                   *(npy_bool *)data_out;
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        *(npy_bool *)dataptr[nop] = temp || *(npy_bool *)dataptr[i];
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#endif
    }
}

static void
bool_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (3 <= 3)
    char *data0 = dataptr[0];
#endif
#if (3 == 2 || 3 == 3)
    char *data1 = dataptr[1];
#endif
#if (3 == 3)
    char *data2 = dataptr[2];
#endif
#if (3 <= 3)
    char *data_out = dataptr[3];
#endif

#if (3 <= 3)
/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 889
        case 6+1:
#  if 3 == 1
            ((npy_bool *)data_out)[6] = ((npy_bool *)data0)[6] ||
                                            ((npy_bool *)data_out)[6];
#  elif 3 == 2
            ((npy_bool *)data_out)[6] =
                            (((npy_bool *)data0)[6] &&
                             ((npy_bool *)data1)[6]) ||
                                ((npy_bool *)data_out)[6];
#  elif 3 == 3
            ((npy_bool *)data_out)[6] =
                           (((npy_bool *)data0)[6] &&
                            ((npy_bool *)data1)[6] &&
                            ((npy_bool *)data2)[6]) ||
                                ((npy_bool *)data_out)[6];
#  endif

#line 889
        case 5+1:
#  if 3 == 1
            ((npy_bool *)data_out)[5] = ((npy_bool *)data0)[5] ||
                                            ((npy_bool *)data_out)[5];
#  elif 3 == 2
            ((npy_bool *)data_out)[5] =
                            (((npy_bool *)data0)[5] &&
                             ((npy_bool *)data1)[5]) ||
                                ((npy_bool *)data_out)[5];
#  elif 3 == 3
            ((npy_bool *)data_out)[5] =
                           (((npy_bool *)data0)[5] &&
                            ((npy_bool *)data1)[5] &&
                            ((npy_bool *)data2)[5]) ||
                                ((npy_bool *)data_out)[5];
#  endif

#line 889
        case 4+1:
#  if 3 == 1
            ((npy_bool *)data_out)[4] = ((npy_bool *)data0)[4] ||
                                            ((npy_bool *)data_out)[4];
#  elif 3 == 2
            ((npy_bool *)data_out)[4] =
                            (((npy_bool *)data0)[4] &&
                             ((npy_bool *)data1)[4]) ||
                                ((npy_bool *)data_out)[4];
#  elif 3 == 3
            ((npy_bool *)data_out)[4] =
                           (((npy_bool *)data0)[4] &&
                            ((npy_bool *)data1)[4] &&
                            ((npy_bool *)data2)[4]) ||
                                ((npy_bool *)data_out)[4];
#  endif

#line 889
        case 3+1:
#  if 3 == 1
            ((npy_bool *)data_out)[3] = ((npy_bool *)data0)[3] ||
                                            ((npy_bool *)data_out)[3];
#  elif 3 == 2
            ((npy_bool *)data_out)[3] =
                            (((npy_bool *)data0)[3] &&
                             ((npy_bool *)data1)[3]) ||
                                ((npy_bool *)data_out)[3];
#  elif 3 == 3
            ((npy_bool *)data_out)[3] =
                           (((npy_bool *)data0)[3] &&
                            ((npy_bool *)data1)[3] &&
                            ((npy_bool *)data2)[3]) ||
                                ((npy_bool *)data_out)[3];
#  endif

#line 889
        case 2+1:
#  if 3 == 1
            ((npy_bool *)data_out)[2] = ((npy_bool *)data0)[2] ||
                                            ((npy_bool *)data_out)[2];
#  elif 3 == 2
            ((npy_bool *)data_out)[2] =
                            (((npy_bool *)data0)[2] &&
                             ((npy_bool *)data1)[2]) ||
                                ((npy_bool *)data_out)[2];
#  elif 3 == 3
            ((npy_bool *)data_out)[2] =
                           (((npy_bool *)data0)[2] &&
                            ((npy_bool *)data1)[2] &&
                            ((npy_bool *)data2)[2]) ||
                                ((npy_bool *)data_out)[2];
#  endif

#line 889
        case 1+1:
#  if 3 == 1
            ((npy_bool *)data_out)[1] = ((npy_bool *)data0)[1] ||
                                            ((npy_bool *)data_out)[1];
#  elif 3 == 2
            ((npy_bool *)data_out)[1] =
                            (((npy_bool *)data0)[1] &&
                             ((npy_bool *)data1)[1]) ||
                                ((npy_bool *)data_out)[1];
#  elif 3 == 3
            ((npy_bool *)data_out)[1] =
                           (((npy_bool *)data0)[1] &&
                            ((npy_bool *)data1)[1] &&
                            ((npy_bool *)data2)[1]) ||
                                ((npy_bool *)data_out)[1];
#  endif

#line 889
        case 0+1:
#  if 3 == 1
            ((npy_bool *)data_out)[0] = ((npy_bool *)data0)[0] ||
                                            ((npy_bool *)data_out)[0];
#  elif 3 == 2
            ((npy_bool *)data_out)[0] =
                            (((npy_bool *)data0)[0] &&
                             ((npy_bool *)data1)[0]) ||
                                ((npy_bool *)data_out)[0];
#  elif 3 == 3
            ((npy_bool *)data_out)[0] =
                           (((npy_bool *)data0)[0] &&
                            ((npy_bool *)data1)[0] &&
                            ((npy_bool *)data2)[0]) ||
                                ((npy_bool *)data_out)[0];
#  endif

        case 0:
            return;
    }
#endif

/* Unroll the loop by 8 for fixed-size nop */
#if (3 <= 3)
    while (count >= 8) {
        count -= 8;
#else
    while (count--) {
#endif

#  if 3 == 1
#line 923
        *((npy_bool *)data_out + 0) = (*((npy_bool *)data0 + 0)) ||
                                        (*((npy_bool *)data_out + 0));

#line 923
        *((npy_bool *)data_out + 1) = (*((npy_bool *)data0 + 1)) ||
                                        (*((npy_bool *)data_out + 1));

#line 923
        *((npy_bool *)data_out + 2) = (*((npy_bool *)data0 + 2)) ||
                                        (*((npy_bool *)data_out + 2));

#line 923
        *((npy_bool *)data_out + 3) = (*((npy_bool *)data0 + 3)) ||
                                        (*((npy_bool *)data_out + 3));

#line 923
        *((npy_bool *)data_out + 4) = (*((npy_bool *)data0 + 4)) ||
                                        (*((npy_bool *)data_out + 4));

#line 923
        *((npy_bool *)data_out + 5) = (*((npy_bool *)data0 + 5)) ||
                                        (*((npy_bool *)data_out + 5));

#line 923
        *((npy_bool *)data_out + 6) = (*((npy_bool *)data0 + 6)) ||
                                        (*((npy_bool *)data_out + 6));

#line 923
        *((npy_bool *)data_out + 7) = (*((npy_bool *)data0 + 7)) ||
                                        (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  elif 3 == 2
#line 932
        *((npy_bool *)data_out + 0) =
                        ((*((npy_bool *)data0 + 0)) &&
                         (*((npy_bool *)data1 + 0))) ||
                            (*((npy_bool *)data_out + 0));

#line 932
        *((npy_bool *)data_out + 1) =
                        ((*((npy_bool *)data0 + 1)) &&
                         (*((npy_bool *)data1 + 1))) ||
                            (*((npy_bool *)data_out + 1));

#line 932
        *((npy_bool *)data_out + 2) =
                        ((*((npy_bool *)data0 + 2)) &&
                         (*((npy_bool *)data1 + 2))) ||
                            (*((npy_bool *)data_out + 2));

#line 932
        *((npy_bool *)data_out + 3) =
                        ((*((npy_bool *)data0 + 3)) &&
                         (*((npy_bool *)data1 + 3))) ||
                            (*((npy_bool *)data_out + 3));

#line 932
        *((npy_bool *)data_out + 4) =
                        ((*((npy_bool *)data0 + 4)) &&
                         (*((npy_bool *)data1 + 4))) ||
                            (*((npy_bool *)data_out + 4));

#line 932
        *((npy_bool *)data_out + 5) =
                        ((*((npy_bool *)data0 + 5)) &&
                         (*((npy_bool *)data1 + 5))) ||
                            (*((npy_bool *)data_out + 5));

#line 932
        *((npy_bool *)data_out + 6) =
                        ((*((npy_bool *)data0 + 6)) &&
                         (*((npy_bool *)data1 + 6))) ||
                            (*((npy_bool *)data_out + 6));

#line 932
        *((npy_bool *)data_out + 7) =
                        ((*((npy_bool *)data0 + 7)) &&
                         (*((npy_bool *)data1 + 7))) ||
                            (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data1 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  elif 3 == 3
#line 944
        *((npy_bool *)data_out + 0) =
                       ((*((npy_bool *)data0 + 0)) &&
                        (*((npy_bool *)data1 + 0)) &&
                        (*((npy_bool *)data2 + 0))) ||
                            (*((npy_bool *)data_out + 0));

#line 944
        *((npy_bool *)data_out + 1) =
                       ((*((npy_bool *)data0 + 1)) &&
                        (*((npy_bool *)data1 + 1)) &&
                        (*((npy_bool *)data2 + 1))) ||
                            (*((npy_bool *)data_out + 1));

#line 944
        *((npy_bool *)data_out + 2) =
                       ((*((npy_bool *)data0 + 2)) &&
                        (*((npy_bool *)data1 + 2)) &&
                        (*((npy_bool *)data2 + 2))) ||
                            (*((npy_bool *)data_out + 2));

#line 944
        *((npy_bool *)data_out + 3) =
                       ((*((npy_bool *)data0 + 3)) &&
                        (*((npy_bool *)data1 + 3)) &&
                        (*((npy_bool *)data2 + 3))) ||
                            (*((npy_bool *)data_out + 3));

#line 944
        *((npy_bool *)data_out + 4) =
                       ((*((npy_bool *)data0 + 4)) &&
                        (*((npy_bool *)data1 + 4)) &&
                        (*((npy_bool *)data2 + 4))) ||
                            (*((npy_bool *)data_out + 4));

#line 944
        *((npy_bool *)data_out + 5) =
                       ((*((npy_bool *)data0 + 5)) &&
                        (*((npy_bool *)data1 + 5)) &&
                        (*((npy_bool *)data2 + 5))) ||
                            (*((npy_bool *)data_out + 5));

#line 944
        *((npy_bool *)data_out + 6) =
                       ((*((npy_bool *)data0 + 6)) &&
                        (*((npy_bool *)data1 + 6)) &&
                        (*((npy_bool *)data2 + 6))) ||
                            (*((npy_bool *)data_out + 6));

#line 944
        *((npy_bool *)data_out + 7) =
                       ((*((npy_bool *)data0 + 7)) &&
                        (*((npy_bool *)data1 + 7)) &&
                        (*((npy_bool *)data2 + 7))) ||
                            (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data1 += 8*sizeof(npy_bool);
        data2 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        *(npy_bool *)dataptr[nop] = temp || *(npy_bool *)dataptr[i];
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_bool);
        }
#  endif
    }

    /* If the loop was unrolled, we need to finish it off */
#if (3 <= 3)
    goto finish_after_unrolled_loop;
#endif
}

static void
bool_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    npy_bool accum = 0;

#if (3 <= 3)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (3 == 2 || 3 == 3)
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (3 == 3)
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    while (count--) {
#if 3 == 1
        accum = *(npy_bool *)data0 || accum;
        data0 += stride0;
#elif 3 == 2
        accum = (*(npy_bool *)data0 && *(npy_bool *)data1) || accum;
        data0 += stride0;
        data1 += stride1;
#elif 3 == 3
        accum = (*(npy_bool *)data0 &&
                 *(npy_bool *)data1 &&
                 *(npy_bool *)data2) || accum;
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        accum = temp || accum;
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#endif
    }

#  if 3 <= 3
    *((npy_bool *)dataptr[3]) = accum || *((npy_bool *)dataptr[3]);
#  else
    *((npy_bool *)dataptr[nop]) = accum || *((npy_bool *)dataptr[nop]);
#  endif
}


#line 807

static void
bool_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 <= 3)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3)
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3)
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif
#if (1000 <= 3)
    char *data_out = dataptr[1000];
    npy_intp stride_out = strides[1000];
#endif

    while (count--) {
#if 1000 == 1
        *(npy_bool *)data_out = *(npy_bool *)data0 ||
                                  *(npy_bool *)data_out;
        data0 += stride0;
        data_out += stride_out;
#elif 1000 == 2
        *(npy_bool *)data_out = (*(npy_bool *)data0 &&
                                   *(npy_bool *)data1) ||
                                   *(npy_bool *)data_out;
        data0 += stride0;
        data1 += stride1;
        data_out += stride_out;
#elif 1000 == 3
        *(npy_bool *)data_out = (*(npy_bool *)data0 &&
                                   *(npy_bool *)data1 &&
                                   *(npy_bool *)data2) ||
                                   *(npy_bool *)data_out;
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
        data_out += stride_out;
#else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        *(npy_bool *)dataptr[nop] = temp || *(npy_bool *)dataptr[i];
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#endif
    }
}

static void
bool_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
#if (1000 <= 3)
    char *data0 = dataptr[0];
#endif
#if (1000 == 2 || 1000 == 3)
    char *data1 = dataptr[1];
#endif
#if (1000 == 3)
    char *data2 = dataptr[2];
#endif
#if (1000 <= 3)
    char *data_out = dataptr[1000];
#endif

#if (1000 <= 3)
/* This is placed before the main loop to make small counts faster */
finish_after_unrolled_loop:
    switch (count) {
#line 889
        case 6+1:
#  if 1000 == 1
            ((npy_bool *)data_out)[6] = ((npy_bool *)data0)[6] ||
                                            ((npy_bool *)data_out)[6];
#  elif 1000 == 2
            ((npy_bool *)data_out)[6] =
                            (((npy_bool *)data0)[6] &&
                             ((npy_bool *)data1)[6]) ||
                                ((npy_bool *)data_out)[6];
#  elif 1000 == 3
            ((npy_bool *)data_out)[6] =
                           (((npy_bool *)data0)[6] &&
                            ((npy_bool *)data1)[6] &&
                            ((npy_bool *)data2)[6]) ||
                                ((npy_bool *)data_out)[6];
#  endif

#line 889
        case 5+1:
#  if 1000 == 1
            ((npy_bool *)data_out)[5] = ((npy_bool *)data0)[5] ||
                                            ((npy_bool *)data_out)[5];
#  elif 1000 == 2
            ((npy_bool *)data_out)[5] =
                            (((npy_bool *)data0)[5] &&
                             ((npy_bool *)data1)[5]) ||
                                ((npy_bool *)data_out)[5];
#  elif 1000 == 3
            ((npy_bool *)data_out)[5] =
                           (((npy_bool *)data0)[5] &&
                            ((npy_bool *)data1)[5] &&
                            ((npy_bool *)data2)[5]) ||
                                ((npy_bool *)data_out)[5];
#  endif

#line 889
        case 4+1:
#  if 1000 == 1
            ((npy_bool *)data_out)[4] = ((npy_bool *)data0)[4] ||
                                            ((npy_bool *)data_out)[4];
#  elif 1000 == 2
            ((npy_bool *)data_out)[4] =
                            (((npy_bool *)data0)[4] &&
                             ((npy_bool *)data1)[4]) ||
                                ((npy_bool *)data_out)[4];
#  elif 1000 == 3
            ((npy_bool *)data_out)[4] =
                           (((npy_bool *)data0)[4] &&
                            ((npy_bool *)data1)[4] &&
                            ((npy_bool *)data2)[4]) ||
                                ((npy_bool *)data_out)[4];
#  endif

#line 889
        case 3+1:
#  if 1000 == 1
            ((npy_bool *)data_out)[3] = ((npy_bool *)data0)[3] ||
                                            ((npy_bool *)data_out)[3];
#  elif 1000 == 2
            ((npy_bool *)data_out)[3] =
                            (((npy_bool *)data0)[3] &&
                             ((npy_bool *)data1)[3]) ||
                                ((npy_bool *)data_out)[3];
#  elif 1000 == 3
            ((npy_bool *)data_out)[3] =
                           (((npy_bool *)data0)[3] &&
                            ((npy_bool *)data1)[3] &&
                            ((npy_bool *)data2)[3]) ||
                                ((npy_bool *)data_out)[3];
#  endif

#line 889
        case 2+1:
#  if 1000 == 1
            ((npy_bool *)data_out)[2] = ((npy_bool *)data0)[2] ||
                                            ((npy_bool *)data_out)[2];
#  elif 1000 == 2
            ((npy_bool *)data_out)[2] =
                            (((npy_bool *)data0)[2] &&
                             ((npy_bool *)data1)[2]) ||
                                ((npy_bool *)data_out)[2];
#  elif 1000 == 3
            ((npy_bool *)data_out)[2] =
                           (((npy_bool *)data0)[2] &&
                            ((npy_bool *)data1)[2] &&
                            ((npy_bool *)data2)[2]) ||
                                ((npy_bool *)data_out)[2];
#  endif

#line 889
        case 1+1:
#  if 1000 == 1
            ((npy_bool *)data_out)[1] = ((npy_bool *)data0)[1] ||
                                            ((npy_bool *)data_out)[1];
#  elif 1000 == 2
            ((npy_bool *)data_out)[1] =
                            (((npy_bool *)data0)[1] &&
                             ((npy_bool *)data1)[1]) ||
                                ((npy_bool *)data_out)[1];
#  elif 1000 == 3
            ((npy_bool *)data_out)[1] =
                           (((npy_bool *)data0)[1] &&
                            ((npy_bool *)data1)[1] &&
                            ((npy_bool *)data2)[1]) ||
                                ((npy_bool *)data_out)[1];
#  endif

#line 889
        case 0+1:
#  if 1000 == 1
            ((npy_bool *)data_out)[0] = ((npy_bool *)data0)[0] ||
                                            ((npy_bool *)data_out)[0];
#  elif 1000 == 2
            ((npy_bool *)data_out)[0] =
                            (((npy_bool *)data0)[0] &&
                             ((npy_bool *)data1)[0]) ||
                                ((npy_bool *)data_out)[0];
#  elif 1000 == 3
            ((npy_bool *)data_out)[0] =
                           (((npy_bool *)data0)[0] &&
                            ((npy_bool *)data1)[0] &&
                            ((npy_bool *)data2)[0]) ||
                                ((npy_bool *)data_out)[0];
#  endif

        case 0:
            return;
    }
#endif

/* Unroll the loop by 8 for fixed-size nop */
#if (1000 <= 3)
    while (count >= 8) {
        count -= 8;
#else
    while (count--) {
#endif

#  if 1000 == 1
#line 923
        *((npy_bool *)data_out + 0) = (*((npy_bool *)data0 + 0)) ||
                                        (*((npy_bool *)data_out + 0));

#line 923
        *((npy_bool *)data_out + 1) = (*((npy_bool *)data0 + 1)) ||
                                        (*((npy_bool *)data_out + 1));

#line 923
        *((npy_bool *)data_out + 2) = (*((npy_bool *)data0 + 2)) ||
                                        (*((npy_bool *)data_out + 2));

#line 923
        *((npy_bool *)data_out + 3) = (*((npy_bool *)data0 + 3)) ||
                                        (*((npy_bool *)data_out + 3));

#line 923
        *((npy_bool *)data_out + 4) = (*((npy_bool *)data0 + 4)) ||
                                        (*((npy_bool *)data_out + 4));

#line 923
        *((npy_bool *)data_out + 5) = (*((npy_bool *)data0 + 5)) ||
                                        (*((npy_bool *)data_out + 5));

#line 923
        *((npy_bool *)data_out + 6) = (*((npy_bool *)data0 + 6)) ||
                                        (*((npy_bool *)data_out + 6));

#line 923
        *((npy_bool *)data_out + 7) = (*((npy_bool *)data0 + 7)) ||
                                        (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  elif 1000 == 2
#line 932
        *((npy_bool *)data_out + 0) =
                        ((*((npy_bool *)data0 + 0)) &&
                         (*((npy_bool *)data1 + 0))) ||
                            (*((npy_bool *)data_out + 0));

#line 932
        *((npy_bool *)data_out + 1) =
                        ((*((npy_bool *)data0 + 1)) &&
                         (*((npy_bool *)data1 + 1))) ||
                            (*((npy_bool *)data_out + 1));

#line 932
        *((npy_bool *)data_out + 2) =
                        ((*((npy_bool *)data0 + 2)) &&
                         (*((npy_bool *)data1 + 2))) ||
                            (*((npy_bool *)data_out + 2));

#line 932
        *((npy_bool *)data_out + 3) =
                        ((*((npy_bool *)data0 + 3)) &&
                         (*((npy_bool *)data1 + 3))) ||
                            (*((npy_bool *)data_out + 3));

#line 932
        *((npy_bool *)data_out + 4) =
                        ((*((npy_bool *)data0 + 4)) &&
                         (*((npy_bool *)data1 + 4))) ||
                            (*((npy_bool *)data_out + 4));

#line 932
        *((npy_bool *)data_out + 5) =
                        ((*((npy_bool *)data0 + 5)) &&
                         (*((npy_bool *)data1 + 5))) ||
                            (*((npy_bool *)data_out + 5));

#line 932
        *((npy_bool *)data_out + 6) =
                        ((*((npy_bool *)data0 + 6)) &&
                         (*((npy_bool *)data1 + 6))) ||
                            (*((npy_bool *)data_out + 6));

#line 932
        *((npy_bool *)data_out + 7) =
                        ((*((npy_bool *)data0 + 7)) &&
                         (*((npy_bool *)data1 + 7))) ||
                            (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data1 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  elif 1000 == 3
#line 944
        *((npy_bool *)data_out + 0) =
                       ((*((npy_bool *)data0 + 0)) &&
                        (*((npy_bool *)data1 + 0)) &&
                        (*((npy_bool *)data2 + 0))) ||
                            (*((npy_bool *)data_out + 0));

#line 944
        *((npy_bool *)data_out + 1) =
                       ((*((npy_bool *)data0 + 1)) &&
                        (*((npy_bool *)data1 + 1)) &&
                        (*((npy_bool *)data2 + 1))) ||
                            (*((npy_bool *)data_out + 1));

#line 944
        *((npy_bool *)data_out + 2) =
                       ((*((npy_bool *)data0 + 2)) &&
                        (*((npy_bool *)data1 + 2)) &&
                        (*((npy_bool *)data2 + 2))) ||
                            (*((npy_bool *)data_out + 2));

#line 944
        *((npy_bool *)data_out + 3) =
                       ((*((npy_bool *)data0 + 3)) &&
                        (*((npy_bool *)data1 + 3)) &&
                        (*((npy_bool *)data2 + 3))) ||
                            (*((npy_bool *)data_out + 3));

#line 944
        *((npy_bool *)data_out + 4) =
                       ((*((npy_bool *)data0 + 4)) &&
                        (*((npy_bool *)data1 + 4)) &&
                        (*((npy_bool *)data2 + 4))) ||
                            (*((npy_bool *)data_out + 4));

#line 944
        *((npy_bool *)data_out + 5) =
                       ((*((npy_bool *)data0 + 5)) &&
                        (*((npy_bool *)data1 + 5)) &&
                        (*((npy_bool *)data2 + 5))) ||
                            (*((npy_bool *)data_out + 5));

#line 944
        *((npy_bool *)data_out + 6) =
                       ((*((npy_bool *)data0 + 6)) &&
                        (*((npy_bool *)data1 + 6)) &&
                        (*((npy_bool *)data2 + 6))) ||
                            (*((npy_bool *)data_out + 6));

#line 944
        *((npy_bool *)data_out + 7) =
                       ((*((npy_bool *)data0 + 7)) &&
                        (*((npy_bool *)data1 + 7)) &&
                        (*((npy_bool *)data2 + 7))) ||
                            (*((npy_bool *)data_out + 7));

        data0 += 8*sizeof(npy_bool);
        data1 += 8*sizeof(npy_bool);
        data2 += 8*sizeof(npy_bool);
        data_out += 8*sizeof(npy_bool);
#  else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        *(npy_bool *)dataptr[nop] = temp || *(npy_bool *)dataptr[i];
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += sizeof(npy_bool);
        }
#  endif
    }

    /* If the loop was unrolled, we need to finish it off */
#if (1000 <= 3)
    goto finish_after_unrolled_loop;
#endif
}

static void
bool_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    npy_bool accum = 0;

#if (1000 <= 3)
    char *data0 = dataptr[0];
    npy_intp stride0 = strides[0];
#endif
#if (1000 == 2 || 1000 == 3)
    char *data1 = dataptr[1];
    npy_intp stride1 = strides[1];
#endif
#if (1000 == 3)
    char *data2 = dataptr[2];
    npy_intp stride2 = strides[2];
#endif

    while (count--) {
#if 1000 == 1
        accum = *(npy_bool *)data0 || accum;
        data0 += stride0;
#elif 1000 == 2
        accum = (*(npy_bool *)data0 && *(npy_bool *)data1) || accum;
        data0 += stride0;
        data1 += stride1;
#elif 1000 == 3
        accum = (*(npy_bool *)data0 &&
                 *(npy_bool *)data1 &&
                 *(npy_bool *)data2) || accum;
        data0 += stride0;
        data1 += stride1;
        data2 += stride2;
#else
        npy_bool temp = *(npy_bool *)dataptr[0];
        int i;
        for (i = 1; i < nop; ++i) {
            temp = temp && *(npy_bool *)dataptr[i];
        }
        accum = temp || accum;
        for (i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
#endif
    }

#  if 1000 <= 3
    *((npy_bool *)dataptr[1000]) = accum || *((npy_bool *)dataptr[1000]);
#  else
    *((npy_bool *)dataptr[nop]) = accum || *((npy_bool *)dataptr[nop]);
#  endif
}



#line 1044
static void
object_sum_of_products_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_contig_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_contig_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_contig_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_contig_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_outstride0_any(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_outstride0_one(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_outstride0_two(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}

#line 1044
static void
object_sum_of_products_outstride0_three(int nop, char **dataptr,
                                npy_intp const *strides, npy_intp count)
{
    while(count--){
        PyObject *prod = *(PyObject **)dataptr[0];
        if (!prod) {
            prod = Py_None;  // convention is to treat nulls as None
        }
        Py_INCREF(prod);
        for (int i = 1; i < nop; ++i){
            PyObject *curr = *(PyObject **)dataptr[i];
            if (!curr) {
                curr = Py_None;  // convention is to treat nulls as None
            }
            Py_SETREF(prod, PyNumber_Multiply(prod, curr));
            if (!prod) {
                return;
            }
        }

        PyObject *sum = PyNumber_Add(*(PyObject **)dataptr[nop], prod);
        Py_DECREF(prod);
        if (!sum) {
            return;
        }
        
        Py_XDECREF(*(PyObject **)dataptr[nop]);
        *(PyObject **)dataptr[nop] = sum;
        for (int i = 0; i <= nop; ++i) {
            dataptr[i] += strides[i];
        }
    }
}


/* These tables need to match up with the type enum */
static sum_of_products_fn
_contig_outstride0_unary_specialization_table[NPY_NTYPES] = {
#line 1105
#if 0
    &bool_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &byte_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &ubyte_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &short_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &ushort_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &int_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &uint_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &long_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &ulong_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &longlong_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &ulonglong_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &float_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &double_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &longdouble_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &cfloat_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &cdouble_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &clongdouble_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 0
    &object_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 0
    &string_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 0
    &unicode_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 0
    &void_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 0
    &datetime_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 0
    &timedelta_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

#line 1105
#if 1
    &half_sum_of_products_contig_outstride0_one,
#else
    NULL,
#endif

}; /* End of _contig_outstride0_unary_specialization_table */

static sum_of_products_fn _binary_specialization_table[NPY_NTYPES][5] = {
#line 1136
#if 0
{
    &bool_sum_of_products_stride0_contig_outstride0_two,
    &bool_sum_of_products_stride0_contig_outcontig_two,
    &bool_sum_of_products_contig_stride0_outstride0_two,
    &bool_sum_of_products_contig_stride0_outcontig_two,
    &bool_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &byte_sum_of_products_stride0_contig_outstride0_two,
    &byte_sum_of_products_stride0_contig_outcontig_two,
    &byte_sum_of_products_contig_stride0_outstride0_two,
    &byte_sum_of_products_contig_stride0_outcontig_two,
    &byte_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &ubyte_sum_of_products_stride0_contig_outstride0_two,
    &ubyte_sum_of_products_stride0_contig_outcontig_two,
    &ubyte_sum_of_products_contig_stride0_outstride0_two,
    &ubyte_sum_of_products_contig_stride0_outcontig_two,
    &ubyte_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &short_sum_of_products_stride0_contig_outstride0_two,
    &short_sum_of_products_stride0_contig_outcontig_two,
    &short_sum_of_products_contig_stride0_outstride0_two,
    &short_sum_of_products_contig_stride0_outcontig_two,
    &short_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &ushort_sum_of_products_stride0_contig_outstride0_two,
    &ushort_sum_of_products_stride0_contig_outcontig_two,
    &ushort_sum_of_products_contig_stride0_outstride0_two,
    &ushort_sum_of_products_contig_stride0_outcontig_two,
    &ushort_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &int_sum_of_products_stride0_contig_outstride0_two,
    &int_sum_of_products_stride0_contig_outcontig_two,
    &int_sum_of_products_contig_stride0_outstride0_two,
    &int_sum_of_products_contig_stride0_outcontig_two,
    &int_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &uint_sum_of_products_stride0_contig_outstride0_two,
    &uint_sum_of_products_stride0_contig_outcontig_two,
    &uint_sum_of_products_contig_stride0_outstride0_two,
    &uint_sum_of_products_contig_stride0_outcontig_two,
    &uint_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &long_sum_of_products_stride0_contig_outstride0_two,
    &long_sum_of_products_stride0_contig_outcontig_two,
    &long_sum_of_products_contig_stride0_outstride0_two,
    &long_sum_of_products_contig_stride0_outcontig_two,
    &long_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &ulong_sum_of_products_stride0_contig_outstride0_two,
    &ulong_sum_of_products_stride0_contig_outcontig_two,
    &ulong_sum_of_products_contig_stride0_outstride0_two,
    &ulong_sum_of_products_contig_stride0_outcontig_two,
    &ulong_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &longlong_sum_of_products_stride0_contig_outstride0_two,
    &longlong_sum_of_products_stride0_contig_outcontig_two,
    &longlong_sum_of_products_contig_stride0_outstride0_two,
    &longlong_sum_of_products_contig_stride0_outcontig_two,
    &longlong_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &ulonglong_sum_of_products_stride0_contig_outstride0_two,
    &ulonglong_sum_of_products_stride0_contig_outcontig_two,
    &ulonglong_sum_of_products_contig_stride0_outstride0_two,
    &ulonglong_sum_of_products_contig_stride0_outcontig_two,
    &ulonglong_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &float_sum_of_products_stride0_contig_outstride0_two,
    &float_sum_of_products_stride0_contig_outcontig_two,
    &float_sum_of_products_contig_stride0_outstride0_two,
    &float_sum_of_products_contig_stride0_outcontig_two,
    &float_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &double_sum_of_products_stride0_contig_outstride0_two,
    &double_sum_of_products_stride0_contig_outcontig_two,
    &double_sum_of_products_contig_stride0_outstride0_two,
    &double_sum_of_products_contig_stride0_outcontig_two,
    &double_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &longdouble_sum_of_products_stride0_contig_outstride0_two,
    &longdouble_sum_of_products_stride0_contig_outcontig_two,
    &longdouble_sum_of_products_contig_stride0_outstride0_two,
    &longdouble_sum_of_products_contig_stride0_outcontig_two,
    &longdouble_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &cfloat_sum_of_products_stride0_contig_outstride0_two,
    &cfloat_sum_of_products_stride0_contig_outcontig_two,
    &cfloat_sum_of_products_contig_stride0_outstride0_two,
    &cfloat_sum_of_products_contig_stride0_outcontig_two,
    &cfloat_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &cdouble_sum_of_products_stride0_contig_outstride0_two,
    &cdouble_sum_of_products_stride0_contig_outcontig_two,
    &cdouble_sum_of_products_contig_stride0_outstride0_two,
    &cdouble_sum_of_products_contig_stride0_outcontig_two,
    &cdouble_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &clongdouble_sum_of_products_stride0_contig_outstride0_two,
    &clongdouble_sum_of_products_stride0_contig_outcontig_two,
    &clongdouble_sum_of_products_contig_stride0_outstride0_two,
    &clongdouble_sum_of_products_contig_stride0_outcontig_two,
    &clongdouble_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &object_sum_of_products_stride0_contig_outstride0_two,
    &object_sum_of_products_stride0_contig_outcontig_two,
    &object_sum_of_products_contig_stride0_outstride0_two,
    &object_sum_of_products_contig_stride0_outcontig_two,
    &object_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &string_sum_of_products_stride0_contig_outstride0_two,
    &string_sum_of_products_stride0_contig_outcontig_two,
    &string_sum_of_products_contig_stride0_outstride0_two,
    &string_sum_of_products_contig_stride0_outcontig_two,
    &string_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &unicode_sum_of_products_stride0_contig_outstride0_two,
    &unicode_sum_of_products_stride0_contig_outcontig_two,
    &unicode_sum_of_products_contig_stride0_outstride0_two,
    &unicode_sum_of_products_contig_stride0_outcontig_two,
    &unicode_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &void_sum_of_products_stride0_contig_outstride0_two,
    &void_sum_of_products_stride0_contig_outcontig_two,
    &void_sum_of_products_contig_stride0_outstride0_two,
    &void_sum_of_products_contig_stride0_outcontig_two,
    &void_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &datetime_sum_of_products_stride0_contig_outstride0_two,
    &datetime_sum_of_products_stride0_contig_outcontig_two,
    &datetime_sum_of_products_contig_stride0_outstride0_two,
    &datetime_sum_of_products_contig_stride0_outcontig_two,
    &datetime_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 0
{
    &timedelta_sum_of_products_stride0_contig_outstride0_two,
    &timedelta_sum_of_products_stride0_contig_outcontig_two,
    &timedelta_sum_of_products_contig_stride0_outstride0_two,
    &timedelta_sum_of_products_contig_stride0_outcontig_two,
    &timedelta_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

#line 1136
#if 1
{
    &half_sum_of_products_stride0_contig_outstride0_two,
    &half_sum_of_products_stride0_contig_outcontig_two,
    &half_sum_of_products_contig_stride0_outstride0_two,
    &half_sum_of_products_contig_stride0_outcontig_two,
    &half_sum_of_products_contig_contig_outstride0_two,
},
#else
    {NULL, NULL, NULL, NULL, NULL},
#endif

}; /* End of _binary_specialization_table */

static sum_of_products_fn _outstride0_specialized_table[NPY_NTYPES][4] = {
#line 1173
#if 1
{
    &bool_sum_of_products_outstride0_any,
    &bool_sum_of_products_outstride0_one,
    &bool_sum_of_products_outstride0_two,
    &bool_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &byte_sum_of_products_outstride0_any,
    &byte_sum_of_products_outstride0_one,
    &byte_sum_of_products_outstride0_two,
    &byte_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &ubyte_sum_of_products_outstride0_any,
    &ubyte_sum_of_products_outstride0_one,
    &ubyte_sum_of_products_outstride0_two,
    &ubyte_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &short_sum_of_products_outstride0_any,
    &short_sum_of_products_outstride0_one,
    &short_sum_of_products_outstride0_two,
    &short_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &ushort_sum_of_products_outstride0_any,
    &ushort_sum_of_products_outstride0_one,
    &ushort_sum_of_products_outstride0_two,
    &ushort_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &int_sum_of_products_outstride0_any,
    &int_sum_of_products_outstride0_one,
    &int_sum_of_products_outstride0_two,
    &int_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &uint_sum_of_products_outstride0_any,
    &uint_sum_of_products_outstride0_one,
    &uint_sum_of_products_outstride0_two,
    &uint_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &long_sum_of_products_outstride0_any,
    &long_sum_of_products_outstride0_one,
    &long_sum_of_products_outstride0_two,
    &long_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &ulong_sum_of_products_outstride0_any,
    &ulong_sum_of_products_outstride0_one,
    &ulong_sum_of_products_outstride0_two,
    &ulong_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &longlong_sum_of_products_outstride0_any,
    &longlong_sum_of_products_outstride0_one,
    &longlong_sum_of_products_outstride0_two,
    &longlong_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &ulonglong_sum_of_products_outstride0_any,
    &ulonglong_sum_of_products_outstride0_one,
    &ulonglong_sum_of_products_outstride0_two,
    &ulonglong_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &float_sum_of_products_outstride0_any,
    &float_sum_of_products_outstride0_one,
    &float_sum_of_products_outstride0_two,
    &float_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &double_sum_of_products_outstride0_any,
    &double_sum_of_products_outstride0_one,
    &double_sum_of_products_outstride0_two,
    &double_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &longdouble_sum_of_products_outstride0_any,
    &longdouble_sum_of_products_outstride0_one,
    &longdouble_sum_of_products_outstride0_two,
    &longdouble_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &cfloat_sum_of_products_outstride0_any,
    &cfloat_sum_of_products_outstride0_one,
    &cfloat_sum_of_products_outstride0_two,
    &cfloat_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &cdouble_sum_of_products_outstride0_any,
    &cdouble_sum_of_products_outstride0_one,
    &cdouble_sum_of_products_outstride0_two,
    &cdouble_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &clongdouble_sum_of_products_outstride0_any,
    &clongdouble_sum_of_products_outstride0_one,
    &clongdouble_sum_of_products_outstride0_two,
    &clongdouble_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &object_sum_of_products_outstride0_any,
    &object_sum_of_products_outstride0_one,
    &object_sum_of_products_outstride0_two,
    &object_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 0
{
    &string_sum_of_products_outstride0_any,
    &string_sum_of_products_outstride0_one,
    &string_sum_of_products_outstride0_two,
    &string_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 0
{
    &unicode_sum_of_products_outstride0_any,
    &unicode_sum_of_products_outstride0_one,
    &unicode_sum_of_products_outstride0_two,
    &unicode_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 0
{
    &void_sum_of_products_outstride0_any,
    &void_sum_of_products_outstride0_one,
    &void_sum_of_products_outstride0_two,
    &void_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 0
{
    &datetime_sum_of_products_outstride0_any,
    &datetime_sum_of_products_outstride0_one,
    &datetime_sum_of_products_outstride0_two,
    &datetime_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 0
{
    &timedelta_sum_of_products_outstride0_any,
    &timedelta_sum_of_products_outstride0_one,
    &timedelta_sum_of_products_outstride0_two,
    &timedelta_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1173
#if 1
{
    &half_sum_of_products_outstride0_any,
    &half_sum_of_products_outstride0_one,
    &half_sum_of_products_outstride0_two,
    &half_sum_of_products_outstride0_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

}; /* End of _outstride0_specialized_table */

static sum_of_products_fn _allcontig_specialized_table[NPY_NTYPES][4] = {
#line 1209
#if 1
{
    &bool_sum_of_products_contig_any,
    &bool_sum_of_products_contig_one,
    &bool_sum_of_products_contig_two,
    &bool_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &byte_sum_of_products_contig_any,
    &byte_sum_of_products_contig_one,
    &byte_sum_of_products_contig_two,
    &byte_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &ubyte_sum_of_products_contig_any,
    &ubyte_sum_of_products_contig_one,
    &ubyte_sum_of_products_contig_two,
    &ubyte_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &short_sum_of_products_contig_any,
    &short_sum_of_products_contig_one,
    &short_sum_of_products_contig_two,
    &short_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &ushort_sum_of_products_contig_any,
    &ushort_sum_of_products_contig_one,
    &ushort_sum_of_products_contig_two,
    &ushort_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &int_sum_of_products_contig_any,
    &int_sum_of_products_contig_one,
    &int_sum_of_products_contig_two,
    &int_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &uint_sum_of_products_contig_any,
    &uint_sum_of_products_contig_one,
    &uint_sum_of_products_contig_two,
    &uint_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &long_sum_of_products_contig_any,
    &long_sum_of_products_contig_one,
    &long_sum_of_products_contig_two,
    &long_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &ulong_sum_of_products_contig_any,
    &ulong_sum_of_products_contig_one,
    &ulong_sum_of_products_contig_two,
    &ulong_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &longlong_sum_of_products_contig_any,
    &longlong_sum_of_products_contig_one,
    &longlong_sum_of_products_contig_two,
    &longlong_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &ulonglong_sum_of_products_contig_any,
    &ulonglong_sum_of_products_contig_one,
    &ulonglong_sum_of_products_contig_two,
    &ulonglong_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &float_sum_of_products_contig_any,
    &float_sum_of_products_contig_one,
    &float_sum_of_products_contig_two,
    &float_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &double_sum_of_products_contig_any,
    &double_sum_of_products_contig_one,
    &double_sum_of_products_contig_two,
    &double_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &longdouble_sum_of_products_contig_any,
    &longdouble_sum_of_products_contig_one,
    &longdouble_sum_of_products_contig_two,
    &longdouble_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &cfloat_sum_of_products_contig_any,
    &cfloat_sum_of_products_contig_one,
    &cfloat_sum_of_products_contig_two,
    &cfloat_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &cdouble_sum_of_products_contig_any,
    &cdouble_sum_of_products_contig_one,
    &cdouble_sum_of_products_contig_two,
    &cdouble_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &clongdouble_sum_of_products_contig_any,
    &clongdouble_sum_of_products_contig_one,
    &clongdouble_sum_of_products_contig_two,
    &clongdouble_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &object_sum_of_products_contig_any,
    &object_sum_of_products_contig_one,
    &object_sum_of_products_contig_two,
    &object_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 0
{
    &string_sum_of_products_contig_any,
    &string_sum_of_products_contig_one,
    &string_sum_of_products_contig_two,
    &string_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 0
{
    &unicode_sum_of_products_contig_any,
    &unicode_sum_of_products_contig_one,
    &unicode_sum_of_products_contig_two,
    &unicode_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 0
{
    &void_sum_of_products_contig_any,
    &void_sum_of_products_contig_one,
    &void_sum_of_products_contig_two,
    &void_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 0
{
    &datetime_sum_of_products_contig_any,
    &datetime_sum_of_products_contig_one,
    &datetime_sum_of_products_contig_two,
    &datetime_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 0
{
    &timedelta_sum_of_products_contig_any,
    &timedelta_sum_of_products_contig_one,
    &timedelta_sum_of_products_contig_two,
    &timedelta_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1209
#if 1
{
    &half_sum_of_products_contig_any,
    &half_sum_of_products_contig_one,
    &half_sum_of_products_contig_two,
    &half_sum_of_products_contig_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

}; /* End of _allcontig_specialized_table */

static sum_of_products_fn _unspecialized_table[NPY_NTYPES][4] = {
#line 1245
#if 1
{
    &bool_sum_of_products_any,
    &bool_sum_of_products_one,
    &bool_sum_of_products_two,
    &bool_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &byte_sum_of_products_any,
    &byte_sum_of_products_one,
    &byte_sum_of_products_two,
    &byte_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &ubyte_sum_of_products_any,
    &ubyte_sum_of_products_one,
    &ubyte_sum_of_products_two,
    &ubyte_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &short_sum_of_products_any,
    &short_sum_of_products_one,
    &short_sum_of_products_two,
    &short_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &ushort_sum_of_products_any,
    &ushort_sum_of_products_one,
    &ushort_sum_of_products_two,
    &ushort_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &int_sum_of_products_any,
    &int_sum_of_products_one,
    &int_sum_of_products_two,
    &int_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &uint_sum_of_products_any,
    &uint_sum_of_products_one,
    &uint_sum_of_products_two,
    &uint_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &long_sum_of_products_any,
    &long_sum_of_products_one,
    &long_sum_of_products_two,
    &long_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &ulong_sum_of_products_any,
    &ulong_sum_of_products_one,
    &ulong_sum_of_products_two,
    &ulong_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &longlong_sum_of_products_any,
    &longlong_sum_of_products_one,
    &longlong_sum_of_products_two,
    &longlong_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &ulonglong_sum_of_products_any,
    &ulonglong_sum_of_products_one,
    &ulonglong_sum_of_products_two,
    &ulonglong_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &float_sum_of_products_any,
    &float_sum_of_products_one,
    &float_sum_of_products_two,
    &float_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &double_sum_of_products_any,
    &double_sum_of_products_one,
    &double_sum_of_products_two,
    &double_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &longdouble_sum_of_products_any,
    &longdouble_sum_of_products_one,
    &longdouble_sum_of_products_two,
    &longdouble_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &cfloat_sum_of_products_any,
    &cfloat_sum_of_products_one,
    &cfloat_sum_of_products_two,
    &cfloat_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &cdouble_sum_of_products_any,
    &cdouble_sum_of_products_one,
    &cdouble_sum_of_products_two,
    &cdouble_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &clongdouble_sum_of_products_any,
    &clongdouble_sum_of_products_one,
    &clongdouble_sum_of_products_two,
    &clongdouble_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &object_sum_of_products_any,
    &object_sum_of_products_one,
    &object_sum_of_products_two,
    &object_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 0
{
    &string_sum_of_products_any,
    &string_sum_of_products_one,
    &string_sum_of_products_two,
    &string_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 0
{
    &unicode_sum_of_products_any,
    &unicode_sum_of_products_one,
    &unicode_sum_of_products_two,
    &unicode_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 0
{
    &void_sum_of_products_any,
    &void_sum_of_products_one,
    &void_sum_of_products_two,
    &void_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 0
{
    &datetime_sum_of_products_any,
    &datetime_sum_of_products_one,
    &datetime_sum_of_products_two,
    &datetime_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 0
{
    &timedelta_sum_of_products_any,
    &timedelta_sum_of_products_one,
    &timedelta_sum_of_products_two,
    &timedelta_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

#line 1245
#if 1
{
    &half_sum_of_products_any,
    &half_sum_of_products_one,
    &half_sum_of_products_two,
    &half_sum_of_products_three
},
#else
    {NULL, NULL, NULL, NULL},
#endif

}; /* End of _unnspecialized_table */

NPY_VISIBILITY_HIDDEN sum_of_products_fn
get_sum_of_products_function(int nop, int type_num,
                             npy_intp itemsize, npy_intp const *fixed_strides)
{
    int iop;

    if (type_num >= NPY_NTYPES) {
        return NULL;
    }

    /* contiguous reduction */
    if (nop == 1 && fixed_strides[0] == itemsize && fixed_strides[1] == 0) {
        sum_of_products_fn ret =
            _contig_outstride0_unary_specialization_table[type_num];
        if (ret != NULL) {
            return ret;
        }
    }

    /* nop of 2 has more specializations */
    if (nop == 2) {
        /* Encode the zero/contiguous strides */
        int code;
        code = (fixed_strides[0] == 0) ? 0 :
                    (fixed_strides[0] == itemsize) ? 2*2*1 : 8;
        code += (fixed_strides[1] == 0) ? 0 :
                    (fixed_strides[1] == itemsize) ? 2*1 : 8;
        code += (fixed_strides[2] == 0) ? 0 :
                    (fixed_strides[2] == itemsize) ? 1 : 8;
        if (code >= 2 && code < 7) {
            sum_of_products_fn ret =
                        _binary_specialization_table[type_num][code-2];
            if (ret != NULL) {
                return ret;
            }
        }
    }

    /* Inner loop with an output stride of 0 */
    if (fixed_strides[nop] == 0) {
        return _outstride0_specialized_table[type_num][nop <= 3 ? nop : 0];
    }

    /* Check for all contiguous */
    for (iop = 0; iop < nop + 1; ++iop) {
        if (fixed_strides[iop] != itemsize) {
            break;
        }
    }

    /* Contiguous loop */
    if (iop == nop + 1) {
        return _allcontig_specialized_table[type_num][nop <= 3 ? nop : 0];
    }

    /* None of the above specializations caught it, general loops */
    return _unspecialized_table[type_num][nop <= 3 ? nop : 0];
}

