a newer version of dirtyIFU that works with the current package, the old version did not work anymore for some reason.

procedure dirtyIFU (inimages)

# Quick and dirty reduction of IFU data
#   Purpose: verify seeing, verify centering, verify signal
#            i.e. morning after sanity checks
#
# Author: Kathleen Labrie (2019)
#
# task dirtyIFU=<path>/dirtyIFU.cl
# cl < dispscript.cl

char    inimages    {prompt="List of raw input science frame"}
char    gcalflats   {"", prompt="List of raw GCALflats"}
char    gcalarc     {"", prompt="raw arc"}
char    rawpath     {"adata$", prompt="Location of raw data"}
char    flat        {"", prompt="Already reduced flat"}
char    arc         {"", prompt="Already reduced arg"}
char    dispscript  {"dispscript.cl", prompt="Script to display reduced output"}
char    slits       {"both", prompt="Slit(s) used"}
char    logfile     {"dirtyIFU.log", prompt="Name of logfile"}
bool    verbose     {yes, prompt="Verbose"}
int     status      {0, prompt="Exit status"}
struct  *scanfile   {"", prompt="Internal use only"}

begin
    char    l_inimages = ""
    char    l_gcalflats = ""
    char    l_gcalarc = ""
    char    l_rawpath = ""
    char    l_flat = ""
    char    l_arc = ""
    char    l_dispscript = ""
    char    l_slits = ""
    char    l_logfile = ""
    bool    l_verbose

    char    paramstr, lastchar, errmsg
    char    filename, flatused, arcused
    char    tmpinimg, tmpinflat, tmpinarc
    char    finalprefix, finalfilename
    int     junk
    bool    reduxflat, doscript, reduxarc, dotransform

    cache ("gloginit")

    status = 0

    junk = fscan (inimages, l_inimages)
    junk = fscan (gcalflats, l_gcalflats)
    junk = fscan (gcalarc, l_gcalarc)
    junk = fscan (rawpath, l_rawpath)
    junk = fscan (flat, l_flat)
    junk = fscan (arc, l_arc)
    junk = fscan (dispscript, l_dispscript)
    junk = fscan (slits, l_slits)
    junk = fscan (logfile, l_logfile)
    l_verbose = verbose

    # Make temporary file names
    tmpinimg = mktemp ("tmpinimg")
    tmpinflat = mktemp ("tmpinflat")
    tmpinarc = mktemp ("tmpinarc")

    # Create the list of parameter/value pairs.  One pair per line.
    # All lines combined into one string.  Line delimiter is '\n'.
    paramstr =  "inimages       = "//inimages.p_value//"\n"
    paramstr += "gcalflats      = "//gcalflats.p_value//"\n"
    paramstr += "gcalarc        = "//gcalarc.p_value//"\n"
    paramstr += "rawpath        = "//rawpath.p_value//"\n"
    paramstr += "flat           = "//flat.p_value//"\n"
    paramstr += "arc            = "//arc.p_value//"\n"
    paramstr += "dispscript     = "//dispscript.p_value//"\n"
    paramstr += "slits          = "//slits.p_value//"\n"
    paramstr += "logfile        = "//logfile.p_value//"\n"
    paramstr += "verbose        = "//verbose.p_value

    # Assign a logfile name if not given.  Open logfile and start log.
    # Write parameter/value pairs ("paramstr") to log.
    gloginit (l_logfile, "dirtyIFU", "gmos", paramstr, fl_append+,
        verbose=l_verbose)
    if (gloginit.status != 0) {
        status = gloginit.status
        goto exitnow
    }
    l_logfile = gloginit.logfile.p_value

    # Check dispscript
    if (l_dispscript == "") doscript = no
    else                    doscript = yes

    if (doscript && (yes == access(l_dispscript))) {
        errmsg = "A display script named "//l_dispscript//" already exists."
        status = 102
        glogprint (l_logfile, "dirtyIFU", "status", type="error", errno=status,
            str=errmsg, verbose+)
        goto clean
    }

    ## Ensure rawpath is correct
    lastchar = substr (l_rawpath, strlen (l_rawpath), strlen (l_rawpath))
    if ((l_rawpath != "") && (lastchar != "$") && (lastchar != "/"))
        l_rawpath = l_rawpath//"/"

    # Check inputs
    gemextn (l_inimages, check="exists,mef", process="none", index="",
        extname="", extversion="", ikparams="", omit="kernel,exten",
        replace="^%%"//l_rawpath//"%", outfile="dev$null", logfile=l_logfile,
        verbose=l_verbose)

    if (gemextn.fail_count > 0) {
        errmsg = gemextn.fail_count//" input science frames were not found."
        status = 101
    } else if (gemextn.count == 0) {
        errmsg = "No valid input science frames defined!"
        status = 121
    }

    if (status != 0) {
        glogprint (l_logfile, "dirtyIFU", "status", type="error", errno=status,
            str=errmsg, verbose+)
        goto clean
    } else {
        gemextn (l_inimages, check="", process="none", index="", extname="",
            extversion="", ikparams="", omit="exten", replace="",
            outfile=tmpinimg, logfile=l_logfile, verbose=l_verbose)
    }

    if (l_gcalflats == "") {
        reduxflat = no
    } else {
        reduxflat = yes

        gemextn (l_gcalflats, check="exists,mef", process="none", index="",
            extname="", extversion="", ikparams="", omit="kernel,exten",
            replace="^%%"//l_rawpath//"%", outfile="dev$null",
            logfile=l_logfile, verbose=l_verbose)

        if (gemextn.fail_count > 0) {
            errmsg = gemextn.fail_count//" input GCAL flats were not found."
            status = 101
        } else if (gemextn.count == 0) {
            errmsg = "No input flat frames defined!"
            status = 121

        }

        if (status != 0) {
            glogprint (l_logfile, "dirtyIFU", "status", type="error",
                errno=status, str=errmsg, verbose+)
            goto clean
        } else {
            gemextn (l_gcalflats, check="", process="none", index="",
                extname="", extversion="", ikparams="", omit="", replace="",
                outfile=tmpinflat, logfile=l_logfile, verbose=l_verbose)
        }
    }

    if (l_gcalarc == "") {
        reduxarc = no
    } else {
        reduxarc = yes

        gemextn (l_gcalarc, check="exist,mef", process="none", index="",
            extname="", extversion="", ikparams="", omit="kernel,exten",
            replace="^%%"//l_rawpath//"%", outfile="dev$null",
            logfile=l_logfile, verbose=l_verbose)

        if (gemextn.fail_count > 0) {
            errmsg = gemextn.fail_count//" input GCAL arcs were not found."
            status = 101
        } else if (gemextn.count == 0) {
            errmsg = "No input gcal arc defined!"
            status 121
        }

        if (status != 0) {
            glogprint (l_logfile, "dirtyIFU", "status", type="error",
                errno=status, str=errmsg, verbose+)
            goto clean
        } else {
            gemextn (l_gcalarc, check="", process="none", index="",
                extname="", extversion="", ikparams="", omit="", replace="",
                outfile=tmpinarc, logfile=l_logfile, verbose=l_verbose)
        }
    }

    if (reduxflat) {
        gfreduce (l_gcalflats, outimag="", outpref="default", slits=l_slits,
            fl_nodsh=no, fl_inter=no, fl_vardq=no, fl_addmdf=yes, fl_over=yes,
            fl_trim=yes, fl_bias=no, fl_gscrrej=no, fl_gnsskysub=no,
            fl_extract=yes, fl_gsappwave=yes, fl_wavtran=no, fl_skysub=no,
            fl_fluxcal=no, rawpath=l_rawpath, key_mdf="", mdffile="default",
            mdfdir="gmos$data/", key_biassec="BIASSEC", key_datasec="DATASEC",
            bpmfile="gmos$data/chipgaps.dat", bias="", reference="",
            response="", wavtraname="", sfunction="", extinction="",
            fl_fixnc=no, fl_novlap=yes, perovlap=10., order=1, line=INDEF,
            nsum=10, trace=yes, recenter=yes, thresh=200.,
            function="chebyshev", t_order=5, t_nsum=10, weights="variance",
            gratingdb="gmos$data/GMOSgratings.dat",
            filterdb="gmos$data/GMOSfilters.dat", xoffset=INDEF,
            expr="default", observatory="default", sci_ext="SCI", var_ext="VAR",
            dq_ext="DQ", logfile=l_logfile, verbose=l_verbose)
        if (doscript) {
            scanfile = tmpinflat
            while (fscan (scanfile, filename) != EOF) {
                printf ("gfdisplay erg%s ver=1 \
                    config=gmos$data/gnifu_slitr.cfg \
                    deadfib=gmos$data/gnifu_deadr.cfg\n\n", filename,
                    >> l_dispscript)
            }
            scanfile = ""
        }
        scanfile = tmpinflat
        junk = fscan (scanfile, filename)
        scanfile = ""
        flatused = "erg"//filename
    } else {
        flatused = l_flat
    }

    if (reduxarc) {
        gfreduce (l_gcalarc, outimag="", outpref="default", slits=l_slits,
            fl_nodsh=no, fl_inter=no, fl_vardq=no, fl_addmdf=yes, fl_over=yes,
            fl_trim=yes, fl_bias=no, fl_gscrrej=no, fl_gnsskysub=no,
            fl_extract=yes, fl_gsappwave=yes, fl_wavtran=no, fl_skysub=no,
            fl_fluxcal=no, rawpath=l_rawpath, key_mdf="", mdffile="default",
            mdfdir="gmos$data/", key_biassec="BIASSEC", key_datasec="DATASEC",
            bpmfile="gmos$data/chipgaps.dat", bias="", reference=flatused,
            respons="", wavtraname="", sfunction="", extinction="",
            fl_fixnc=no, fl_novlap=yes, perovlap=10., order=1, line=INDEF,
            nsum=10, trace=no, recenter=no, thresh=200.,
            function="chebyshev", t_order=5, t_nsum=10, weights="variance",
            gratingdb="gmos$data/GMOSgratings.dat",
            filterdb="gmos$data/GMOSfilters.dat", xoffset=INDEF,
            expr="default", observatory="default", sci_ext="SCI", var_ext="VAR",
            dq_ext="DQ", logfile=l_logfile, verbose=l_verbose)

        gswavelength ("erg"//l_gcalarc, fl_inter=yes, nlost=10, ntarget=15,
            threshold=25, coordlis="gmos$data/GCALcuar.dat")

        dotransform = yes
        arcused = "erg"//l_gcalarc

    } else {
        if (l_arc == "") {
            dotransform = no
        } else {
            dotransform = yes
        }
        arcused = l_arc
    }

    gfreduce (l_inimages, outimag="", outpref="default", slits=l_slits,
        fl_nodsh=no, fl_inter=no, fl_vardq=no, fl_addmdf=yes, fl_over=no,
        fl_trim=yes, fl_bias=no, fl_gscrrej=no, fl_gnsskysub=no,
        fl_extract=yes, fl_gsappwave=no,
        fl_wavtran=dotransform, fl_skysub=dotransform,
        fl_fluxcal=no, rawpath=l_rawpath, key_mdf="", mdffile="default",
        mdfdir="gmos$data/", key_biassec="BIASSEC", key_datasec="DATASEC",
        bpmfile="gmos$data/chipgaps.dat", bias="", reference=flatused,
        wavtraname=arcused, sfunction="", extinction="", fl_fixnc=no, fl_novlap=yes,
        perovlap=10., order=1, line=INDEF, nsum=10, trace=no, recenter=yes,
        thresh=200., function="chebyshev", t_order=5, t_nsum=10,
        weights="variance", gratingdb="gmos$data/GMOSgratings.dat",
        filterdb="gmos$data/GMOSfilters.dat", xoffset=INDEF, expr="default",
        observatory="default", sci_ext="SCI", var_ext="VAR", dq_ext="DQ",
        logfile=l_logfile, verbose=l_verbose)

    scanfile = tmpinimg
    while (fscan (scanfile, filename) !=  EOF) {
        if (dotransform) {
            finalprefix = "sterg"
        } else {
            finalprefix = "erg"
        }
        finalfilename = finalprefix//filename
        gfcube (finalfilename, outimage=finalfilename//"_3D",
            outpref="", ssample=0.1)
        if (doscript) {
            printf ("gfdisplay %s out=%s_2D ver=1 \
                config=gmos$data/gnifu_slitr.cfg \
                deadfib=gmos$data/gnifu_deadr.cfg\n\n",
                finalfilename, finalfilename,
                >> l_dispscript)
        }
    }
    scanfile = ""

clean:
    scanfile = ""
    delete (tmpinimg, ver-, >& "dev$null")
    delete (tmpinflat, ver-, >& "dev$null")

    if (status == 0)
        glogclose (l_logfile, "dirtyIFU", fl_success+, verbose=l_verbose)
    else
        glogclose (l_logfile, "dirtyIFU", fl_success-, verbose=l_verbose)

exitnow:
    ;

end

procedure dirtyIFU (inimages)

# Quick and dirty reduction of IFU data
#   Purpose: verify seeing, verify centering, verify signal
#            i.e. morning after sanity checks

char    inimages    {prompt="List of raw input science frame"}
char    gcalflats   {"", prompt="List of raw GCALflats"}
char    rawpath     {"/net/archie/staging/perm/", prompt="Location of raw data"}
char    flat        {"", prompt="Already reduced flat"}
char    dispscript  {"dispscript.cl", prompt="Script to display reduced output"}
char    slits       {"both", prompt="Slit(s) used"}
char    logfile     {"dirtyIFU.log", prompt="Name of logfile"}
bool    verbose     {yes, prompt="Verbose"}
int     status      {0, prompt="Exit status"}
struct  *scanfile   {"", prompt="Internal use only"}

begin
    char    l_inimages = ""
    char    l_gcalflats = ""
    char    l_rawpath = ""
    char    l_flat = ""
    char    l_dispscript = ""
    char    l_slits = ""
    char    l_logfile = ""
    bool    l_verbose

    char    paramstr, lastchar, errmsg
    char    filename, flatused
    char    tmpinimg, tmpinflat
    int     junk
    bool    reduxflat, doscript

    cache ("gloginit")

    status = 0

    junk = fscan (inimages, l_inimages)
    junk = fscan (gcalflats, l_gcalflats)
    junk = fscan (rawpath, l_rawpath)
    junk = fscan (flat, l_flat)
    junk = fscan (dispscript, l_dispscript)
    junk = fscan (slits, l_slits)
    junk = fscan (logfile, l_logfile)
    l_verbose = verbose

    # Make temporary file names
    tmpinimg = mktemp ("tmpinimg")
    tmpinflat = mktemp ("tmpinflat")

    # Create the list of parameter/value pairs.  One pair per line.
    # All lines combined into one string.  Line delimiter is '\n'.
    paramstr =  "inimages       = "//inimages.p_value//"\n"
    paramstr += "gcalflats      = "//gcalflats.p_value//"\n"
    paramstr += "rawpath        = "//rawpath.p_value//"\n"
    paramstr += "flat           = "//flat.p_value//"\n"
    paramstr += "dispscript     = "//dispscript.p_value//"\n"
    paramstr += "slits          = "//slits.p_value//"\n"
    paramstr += "logfile        = "//logfile.p_value//"\n"
    paramstr += "verbose        = "//verbose.p_value

    # Assign a logfile name if not given.  Open logfile and start log.
    # Write parameter/value pairs ("paramstr") to log.
    gloginit (l_logfile, "dirtyIFU", "gmos", paramstr, fl_append+,
        verbose=l_verbose)
    if (gloginit.status != 0) {
        status = gloginit.status
        goto exitnow
    }
    l_logfile = gloginit.logfile.p_value

    # Check dispscript
    if (l_dispscript == "") doscript = no
    else                    doscript = yes

    if (doscript && (yes == access(l_dispscript))) {
        errmsg = "A display script named "//l_dispscript//" already exists."
        status = 102
        glogprint (l_logfile, "dirtyIFU", "status", type="error", errno=status,
            str=errmsg, verbose+)
        goto clean
    }

    ## Ensure rawpath is correct
    lastchar = substr (l_rawpath, strlen (l_rawpath), strlen (l_rawpath))
    if ((l_rawpath != "") && (lastchar != "$") && (lastchar != "/"))
        l_rawpath = l_rawpath//"/"

    # Check inputs
    gemextn (l_inimages, check="exists,mef", process="none", index="",
        extname="", extversion="", ikparams="", omit="kernel,exten",
        replace="^%%"//l_rawpath//"%", outfile="dev$null", logfile=l_logfile,
        verbose=l_verbose)

    if (gemextn.fail_count > 0) {
        errmsg = gemextn.fail_count//" input science frames were not found."
        status = 101
    } else if (gemextn.count == 0) {
        errmsg = "No valid input science frames defined!"
        status = 121
    }

    if (status != 0) {
        glogprint (l_logfile, "dirtyIFU", "status", type="error", errno=status,
            str=errmsg, verbose+)
        goto clean
    } else {
        gemextn (l_inimages, check="", process="none", index="", extname="",
            extversion="", ikparams="", omit="exten", replace="",
            outfile=tmpinimg, logfile=l_logfile, verbose=l_verbose)
    }

    if (l_gcalflats == "") {
        reduxflat = no
    } else {
        reduxflat = yes

        gemextn (l_gcalflats, check="exists,mef", process="none", index="",
            extname="", extversion="", ikparams="", omit="kernel,exten",
            replace="^%%"//l_rawpath//"%", outfile="dev$null",
            logfile=l_logfile, verbose=l_verbose)

        if (gemextn.fail_count > 0) {
            errmsg = gemextn.fail_count//" input GCAL flats were not found."
            status = 101
        } else if (gemextn.count == 0) {
            errmsg = "No input science frames defined!"
            status = 121

        }

        if (status != 0) {
            glogprint (l_logfile, "dirtyIFU", "status", type="error",
                errno=status, str=errmsg, verbose+)
            goto clean
        } else {
            gemextn (l_gcalflats, check="", process="none", index="",
                extname="", extversion="", ikparams="", omit="", replace="",
                outfile=tmpinflat, logfile=l_logfile, verbose=l_verbose)
        }
    }

    if (reduxflat) {
        gfreduce (l_gcalflats, outimag="", outpref="default", slits=l_slits,
            fl_nodsh=no, fl_inter=no, fl_vardq=no, fl_addmdf=yes, fl_over=no,
            fl_trim=yes, fl_bias=no, fl_gscrrej=no, fl_gnsskysub=no,
            fl_extract=yes, fl_gsappwave=yes, fl_wavtran=no, fl_skysub=no,
            fl_fluxcal=no, rawpath=l_rawpath, key_mdf="", mdffile="default",
            mdfdir="gmos$data/", key_biassec="BIASSEC", key_datasec="DATASEC",
            bpmfile="gmos$data/chipgaps.dat", bias="", reference="",
            response="", wavtraname="", sfunction="", extinction="",
            fl_fixnc=no, fl_novlap=yes, perovlap=10., order=1, line=INDEF,
            nsum=10, trace=yes, recenter=yes, thresh=200.,
            function="chebyshev", t_order=5, t_nsum=10, weights="variance",
            gratingdb="gmos$data/GMOSgratings.dat",
            filterdb="gmos$data/GMOSfilters.dat", xoffset=INDEF,
            expr="default", observatory="default", sci_ext="SCI", var_ext="VAR",
            dq_ext="DQ", logfile=l_logfile, verbose=l_verbose)
        if (doscript) {
            scanfile = tmpinflat
            while (fscan (scanfile, filename) != EOF) {
                printf ("gfdisplay erg%s ver=1 \
                    config=gmos$data/gnifu_slitr.cfg \
                    deadfib=gmos$data/gnifu_deadr.cfg\n\n", filename,
                    >> l_dispscript)
            }
            scanfile = ""
        }
        scanfile = tmpinflat
        junk = fscan (scanfile, filename)
        scanfile = ""
        flatused = "erg"//filename
    } else {
        flatused = l_flat
    }

    gfreduce (l_inimages, outimag="", outpref="default", slits=l_slits,
        fl_nodsh=no, fl_inter=no, fl_vardq=no, fl_addmdf=yes, fl_over=no,
        fl_trim=yes, fl_bias=no, fl_gscrrej=yes, fl_gnsskysub=no,
        fl_extract=yes, fl_gsappwave=no, fl_wavtran=no, fl_skysub=yes,
        fl_fluxcal=no, rawpath=l_rawpath, key_mdf="", mdffile="default",
        mdfdir="gmos$data/", key_biassec="BIASSEC", key_datasec="DATASEC",
        bpmfile="gmos$data/chipgaps.dat", bias="", reference=flatused,
        wavtraname="", sfunction="", extinction="", fl_fixnc=no, fl_novlap=yes,
        perovlap=10., order=1, line=INDEF, nsum=10, trace=no, recenter=yes,
        thresh=200., function="chebyshev", t_order=5, t_nsum=10,
        weights="variance", gratingdb="gmos$data/GMOSgratings.dat",
        filterdb="gmos$data/GMOSfilters.dat", xoffset=INDEF, expr="default",
        observatory="default", sci_ext="SCI", var_ext="VAR", dq_ext="DQ",
        logfile=l_logfile, verbose=l_verbose)

    scanfile = tmpinimg
    while (fscan (scanfile, filename) !=  EOF) {
        gfcube ("sexrg"//filename, outimage="sexrg"//filename//"_3D",
            outpref="", ssample=0.1)
        if (doscript) {
            printf ("gfdisplay sexrg%s out=sexrg%s_2D ver=1 \
                config=gmos$data/gnifu_slitr.cfg \
                deadfib=gmos$data/gnifu_deadr.cfg\n\n", filename, filename,
                >> l_dispscript)
        }
    }
    scanfile = ""

clean:
    scanfile = ""
    delete (tmpinimg, ver-, >& "dev$null")
    delete (tmpinflat, ver-, >& "dev$null")

    if (status == 0)
        glogclose (l_logfile, "dirtyIFU", fl_success+, verbose=l_verbose)
    else
        glogclose (l_logfile, "dirtyIFU", fl_success-, verbose=l_verbose)

exitnow:
    ;

end


Illegal cast between address spaces caused a crash in TAS with LLVM 3.5. [A Clang bug, it should not generate such code the first place.]

// TESTING: as_TYPEn

#if __clang_major__ == 3 && __clang_minor__ < 4
typedef const char* string;     /* for backward compatibility */
#else
typedef constant char* string;
#endif

_CL_NOINLINE
void clear_bytes(uchar* p, uchar c, size_t n)
{
  for (size_t i = 0; i < n; ++i) {
    p[i] = c;
  }
}

_CL_NOINLINE
void compare_bytes(
    string name,
    const uchar* dst, size_t dst_size, size_t dst_elsize,
    const uchar* src, size_t src_size, size_t src_elsize)
{
  const size_t n = dst_elsize < src_elsize ? dst_elsize : src_elsize;
  if (dst_size != src_size) {
    printf("FAIL: %s - size mismatch! dst_size: %u src_size: %u\n",
           name, (uint)dst_size, (uint)src_size);
    return;
  }
  for (size_t i = 0; i < n; ++i) {
    if (dst[i] != src[i]) {
      printf("FAIL: %s - byte #: %u expected: %#.2x actual: %#.2x\n",
             name, (uint)i, src[i], dst[i]);
    }
  }
}

kernel void test_as_type()
{
  __attribute__((aligned(128)))
  char data[128] =
  {
    0xe4, 0xf9, 0xb4, 0x88, 0x19, 0x65, 0xa2, 0xb6,
    0xa0, 0xfd, 0xa4, 0xbc, 0x11, 0x9e, 0x8c, 0xb2,
    0x7c, 0x15, 0xae, 0x6b, 0x7d, 0xe5, 0xba, 0x8e,
    0xaa, 0x5a, 0x8b, 0x62, 0xd0, 0xcf, 0x17, 0x92,
    0x6d, 0xa4, 0x80, 0x63, 0x05, 0x89, 0x11, 0x4f,
    0xb3, 0x22, 0x8f, 0x3b, 0x5b, 0x2f, 0x26, 0x6b,
    0xb6, 0x97, 0xea, 0x55, 0xf5, 0xb2, 0x37, 0xdb,
    0x41, 0xbc, 0x03, 0x8e, 0x0f, 0xdb, 0x90, 0x88,
    0x53, 0x54, 0x20, 0x25, 0x8a, 0x77, 0x8d, 0x0b,
    0xcc, 0xf6, 0x79, 0x0e, 0xe4, 0x7d, 0xfb, 0xe9,
    0xb2, 0x08, 0x88, 0x91, 0xb5, 0xa3, 0xc0, 0x58,
    0x54, 0x29, 0x5c, 0xef, 0x74, 0xcd, 0x6e, 0xf5,
    0x1c, 0xd7, 0xe4, 0xf2, 0xc3, 0xb8, 0xee, 0x51,
    0x8b, 0x9e, 0x4e, 0xc4, 0xc8, 0xc9, 0xf4, 0x82,
    0x2d, 0x45, 0xbc, 0xa2, 0xfc, 0x16, 0x09, 0xa0,
    0x45, 0x84, 0xdf, 0xe7, 0xd7, 0x1a, 0x32, 0x25,
  };

#define TEST_AS_TYPE(DST, N, SRC, M)                            \
  {                                                             \
    union { SRC value; uchar raw[sizeof(SRC)]; } src;           \
    union { DST value; uchar raw[sizeof(DST)]; } dst;           \
    clear_bytes(src.raw, 0x44, sizeof(SRC));                    \
    clear_bytes(dst.raw, 0x99, sizeof(DST));                    \
    src.value = *((SRC*)data);                                  \
    dst.value = as_##DST(src.value);                            \
    compare_bytes("as_" #DST "((" #SRC "))",                    \
        dst.raw, sizeof(DST), N, src.raw, sizeof(SRC), M);      \
  }

/* 1 byte */
#define TEST_AS_TYPE_1(DST)              \
  TEST_AS_TYPE(DST, 1, char, 1)          \
  TEST_AS_TYPE(DST, 1, uchar, 1)

  TEST_AS_TYPE_1(char)
  TEST_AS_TYPE_1(uchar)

/* 2 bytes */
#define TEST_AS_TYPE_2(DST)              \
  TEST_AS_TYPE(DST, 2, char2, 2)         \
  TEST_AS_TYPE(DST, 2, uchar2, 2)        \
  TEST_AS_TYPE(DST, 2, short, 2)         \
  TEST_AS_TYPE(DST, 2, ushort, 2)

  TEST_AS_TYPE_2(char2)
  TEST_AS_TYPE_2(uchar2)
  TEST_AS_TYPE_2(short)
  TEST_AS_TYPE_2(ushort)

/* 4 bytes */
#define TEST_AS_TYPE_4(DST, N)           \
  TEST_AS_TYPE(DST, N, char4, 4)         \
  TEST_AS_TYPE(DST, N, uchar4, 4)        \
  TEST_AS_TYPE(DST, N, char3, 3)         \
  TEST_AS_TYPE(DST, N, uchar3, 3)        \
  TEST_AS_TYPE(DST, N, short2, 4)        \
  TEST_AS_TYPE(DST, N, ushort2, 4)       \
  TEST_AS_TYPE(DST, N, int, 4)           \
  TEST_AS_TYPE(DST, N, uint, 4)          \
  TEST_AS_TYPE(DST, N, float, 4)

  TEST_AS_TYPE_4(char4, 4)
  TEST_AS_TYPE_4(uchar4, 4)
  TEST_AS_TYPE_4(char3, 3)
  TEST_AS_TYPE_4(uchar3, 3)
  TEST_AS_TYPE_4(short2, 4)
  TEST_AS_TYPE_4(ushort2, 4)
  TEST_AS_TYPE_4(int, 4)
  TEST_AS_TYPE_4(uint, 4)
  TEST_AS_TYPE_4(float, 4)

/* 8 bytes */
#define TEST_AS_TYPE_8(DST, N)           \
  TEST_AS_TYPE(DST, N, char8, 8)         \
  TEST_AS_TYPE(DST, N, uchar8, 8)        \
  TEST_AS_TYPE(DST, N, short4, 8)        \
  TEST_AS_TYPE(DST, N, ushort4, 8)       \
  TEST_AS_TYPE(DST, N, short3, 6)        \
  TEST_AS_TYPE(DST, N, ushort3, 6)       \
  TEST_AS_TYPE(DST, N, int2, 8)          \
  TEST_AS_TYPE(DST, N, uint2, 8)         \
  __IF_INT64(                            \
  TEST_AS_TYPE(DST, N, long, 8)          \
  TEST_AS_TYPE(DST, N, ulong, 8))        \
  TEST_AS_TYPE(DST, N, float2, 8)        \
  __IF_FP64(                             \
  TEST_AS_TYPE(DST, N, double, 8))

  TEST_AS_TYPE_8(char8, 8)
  TEST_AS_TYPE_8(uchar8, 8)
  TEST_AS_TYPE_8(short4, 8)
  TEST_AS_TYPE_8(ushort4, 8)
  TEST_AS_TYPE_8(short3, 6)
  TEST_AS_TYPE_8(ushort3, 6)
  TEST_AS_TYPE_8(int2, 8)
  TEST_AS_TYPE_8(uint2, 8)
  __IF_INT64(
  TEST_AS_TYPE_8(long, 8)
  TEST_AS_TYPE_8(ulong, 8))
  TEST_AS_TYPE_8(float2, 8)
  __IF_FP64(
  TEST_AS_TYPE_8(double, 8))

/* 16 bytes */
#define TEST_AS_TYPE_16(DST, N)          \
  TEST_AS_TYPE(DST, N, char16, 16)       \
  TEST_AS_TYPE(DST, N, uchar16, 16)      \
  TEST_AS_TYPE(DST, N, short8, 16)       \
  TEST_AS_TYPE(DST, N, ushort8, 16)      \
  TEST_AS_TYPE(DST, N, int4, 16)         \
  TEST_AS_TYPE(DST, N, uint4, 16)        \
  TEST_AS_TYPE(DST, N, int3, 12)         \
  TEST_AS_TYPE(DST, N, uint3, 12)        \
  __IF_INT64(                            \
  TEST_AS_TYPE(DST, N, long2, 16)        \
  TEST_AS_TYPE(DST, N, ulong2, 16))      \
  TEST_AS_TYPE(DST, N, float4, 16)       \
  TEST_AS_TYPE(DST, N, float3, 12)       \
  __IF_FP64(                             \
  TEST_AS_TYPE(DST, N, double2, 16))

  TEST_AS_TYPE_16(char16, 16)
  TEST_AS_TYPE_16(uchar16, 16)
  TEST_AS_TYPE_16(short8, 16)
  TEST_AS_TYPE_16(ushort8, 16)
  TEST_AS_TYPE_16(int4, 16)
  TEST_AS_TYPE_16(uint4, 16)
  TEST_AS_TYPE_16(int3, 12)
  TEST_AS_TYPE_16(uint3, 12)
  __IF_INT64(
  TEST_AS_TYPE_16(long2, 16)
  TEST_AS_TYPE_16(ulong2, 16))
  TEST_AS_TYPE_16(float4, 16)
  TEST_AS_TYPE_16(float3, 12)
  __IF_FP64(
  TEST_AS_TYPE_16(double2, 16))

/* 32 bytes */
#define TEST_AS_TYPE_32(DST, N)           \
  TEST_AS_TYPE(DST, N, short16, 32)       \
  TEST_AS_TYPE(DST, N, ushort16, 32)      \
  TEST_AS_TYPE(DST, N, int8, 32)          \
  TEST_AS_TYPE(DST, N, uint8, 32)         \
  __IF_INT64(                             \
  TEST_AS_TYPE(DST, N, long4, 32)         \
  TEST_AS_TYPE(DST, N, ulong4, 32)        \
  TEST_AS_TYPE(DST, N, long3, 24)         \
  TEST_AS_TYPE(DST, N, ulong3, 24))       \
  TEST_AS_TYPE(DST, N, float8, 32)        \
  __IF_FP64(                              \
  TEST_AS_TYPE(DST, N, double4, 32)       \
  TEST_AS_TYPE(DST, N, double3, 24))

  TEST_AS_TYPE_32(short16, 32)
  TEST_AS_TYPE_32(ushort16, 32)
  TEST_AS_TYPE_32(int8, 32)
  TEST_AS_TYPE_32(uint8, 32)
  __IF_INT64(
  TEST_AS_TYPE_32(long4, 32)
  TEST_AS_TYPE_32(ulong4, 32)
  TEST_AS_TYPE_32(long3, 24)
  TEST_AS_TYPE_32(ulong3, 24))
  TEST_AS_TYPE_32(float8, 32)
  __IF_FP64(
  TEST_AS_TYPE_32(double4, 32)
  TEST_AS_TYPE_32(double3, 24))

/* 64 bytes */
#define TEST_AS_TYPE_64(DST)              \
  TEST_AS_TYPE(DST, 64, int16, 64)        \
  TEST_AS_TYPE(DST, 64, uint16, 64)       \
  __IF_INT64(                             \
  TEST_AS_TYPE(DST, 64, long8, 64)        \
  TEST_AS_TYPE(DST, 64, ulong8, 64))      \
  TEST_AS_TYPE(DST, 64, float16, 64)      \
  __IF_FP64(                              \
  TEST_AS_TYPE(DST, 64, double8, 64))

  TEST_AS_TYPE_64(int16)
  TEST_AS_TYPE_64(uint16)
  __IF_INT64(
  TEST_AS_TYPE_64(long8)
  TEST_AS_TYPE_64(ulong8))
  TEST_AS_TYPE_64(float16)
  __IF_FP64(
  TEST_AS_TYPE_64(double8))

/* 128 bytes */
#define TEST_AS_TYPE_128(DST, N)          \
  __IF_INT64(                             \
  TEST_AS_TYPE(DST, N, long16, 128)       \
  TEST_AS_TYPE(DST, N, ulong16, 128))     \
  __IF_FP64(                              \
  TEST_AS_TYPE(DST, N, double16, 128))

  __IF_INT64(
  TEST_AS_TYPE_128(long16, 128)
  TEST_AS_TYPE_128(ulong16, 128))
  __IF_FP64(
  TEST_AS_TYPE_128(double16, 128))
}

// TESTING: as_TYPEn

#if __clang_major__ == 3 && __clang_minor__ < 4
typedef const char* string;     /* for backward compatibility */
#else
typedef constant char* string;
#endif

__attribute__((aligned(128)))
constant char data[128] =
{
  0xe4, 0xf9, 0xb4, 0x88, 0x19, 0x65, 0xa2, 0xb6,
  0xa0, 0xfd, 0xa4, 0xbc, 0x11, 0x9e, 0x8c, 0xb2,
  0x7c, 0x15, 0xae, 0x6b, 0x7d, 0xe5, 0xba, 0x8e,
  0xaa, 0x5a, 0x8b, 0x62, 0xd0, 0xcf, 0x17, 0x92,
  0x6d, 0xa4, 0x80, 0x63, 0x05, 0x89, 0x11, 0x4f,
  0xb3, 0x22, 0x8f, 0x3b, 0x5b, 0x2f, 0x26, 0x6b,
  0xb6, 0x97, 0xea, 0x55, 0xf5, 0xb2, 0x37, 0xdb,
  0x41, 0xbc, 0x03, 0x8e, 0x0f, 0xdb, 0x90, 0x88,
  0x53, 0x54, 0x20, 0x25, 0x8a, 0x77, 0x8d, 0x0b,
  0xcc, 0xf6, 0x79, 0x0e, 0xe4, 0x7d, 0xfb, 0xe9,
  0xb2, 0x08, 0x88, 0x91, 0xb5, 0xa3, 0xc0, 0x58,
  0x54, 0x29, 0x5c, 0xef, 0x74, 0xcd, 0x6e, 0xf5,
  0x1c, 0xd7, 0xe4, 0xf2, 0xc3, 0xb8, 0xee, 0x51,
  0x8b, 0x9e, 0x4e, 0xc4, 0xc8, 0xc9, 0xf4, 0x82,
  0x2d, 0x45, 0xbc, 0xa2, 0xfc, 0x16, 0x09, 0xa0,
  0x45, 0x84, 0xdf, 0xe7, 0xd7, 0x1a, 0x32, 0x25,
};

_CL_NOINLINE
void clear_bytes(uchar* p, uchar c, size_t n)
{
  for (size_t i = 0; i < n; ++i) {
    p[i] = c;
  }
}

_CL_NOINLINE
void compare_bytes(
    string name,
    const uchar* dst, size_t dst_size, size_t dst_elsize,
    const uchar* src, size_t src_size, size_t src_elsize)
{
  const size_t n = dst_elsize < src_elsize ? dst_elsize : src_elsize;
  if (dst_size != src_size) {
    printf("FAIL: %s - size mismatch! dst_size: %u src_size: %u\n",
           name, (uint)dst_size, (uint)src_size);
    return;
  }
  for (size_t i = 0; i < n; ++i) {
    if (dst[i] != src[i]) {
      printf("FAIL: %s - byte #: %u expected: %#.2x actual: %#.2x\n",
             name, (uint)i, src[i], dst[i]);
    }
  }
}

kernel void test_as_type()
{
#define TEST_AS_TYPE(DST, N, SRC, M)                            \
  {                                                             \
    union { SRC value; uchar raw[sizeof(SRC)]; } src;           \
    union { DST value; uchar raw[sizeof(DST)]; } dst;           \
    clear_bytes(src.raw, 0x44, sizeof(SRC));                    \
    clear_bytes(dst.raw, 0x99, sizeof(DST));                    \
    src.value = *((constant SRC*)data);                         \
    dst.value = as_##DST(src.value);                            \
    compare_bytes("as_" #DST "((" #SRC "))",                    \
        dst.raw, sizeof(DST), N, src.raw, sizeof(SRC), M);      \
  }

/* 1 byte */
#define TEST_AS_TYPE_1(DST)              \
  TEST_AS_TYPE(DST, 1, char, 1)          \
  TEST_AS_TYPE(DST, 1, uchar, 1)

  TEST_AS_TYPE_1(char)
  TEST_AS_TYPE_1(uchar)

/* 2 bytes */
#define TEST_AS_TYPE_2(DST)              \
  TEST_AS_TYPE(DST, 2, char2, 2)         \
  TEST_AS_TYPE(DST, 2, uchar2, 2)        \
  TEST_AS_TYPE(DST, 2, short, 2)         \
  TEST_AS_TYPE(DST, 2, ushort, 2)

  TEST_AS_TYPE_2(char2)
  TEST_AS_TYPE_2(uchar2)
  TEST_AS_TYPE_2(short)
  TEST_AS_TYPE_2(ushort)

/* 4 bytes */
#define TEST_AS_TYPE_4(DST, N)           \
  TEST_AS_TYPE(DST, N, char4, 4)         \
  TEST_AS_TYPE(DST, N, uchar4, 4)        \
  TEST_AS_TYPE(DST, N, char3, 3)         \
  TEST_AS_TYPE(DST, N, uchar3, 3)        \
  TEST_AS_TYPE(DST, N, short2, 4)        \
  TEST_AS_TYPE(DST, N, ushort2, 4)       \
  TEST_AS_TYPE(DST, N, int, 4)           \
  TEST_AS_TYPE(DST, N, uint, 4)          \
  TEST_AS_TYPE(DST, N, float, 4)

  TEST_AS_TYPE_4(char4, 4)
  TEST_AS_TYPE_4(uchar4, 4)
  TEST_AS_TYPE_4(char3, 3)
  TEST_AS_TYPE_4(uchar3, 3)
  TEST_AS_TYPE_4(short2, 4)
  TEST_AS_TYPE_4(ushort2, 4)
  TEST_AS_TYPE_4(int, 4)
  TEST_AS_TYPE_4(uint, 4)
  TEST_AS_TYPE_4(float, 4)

/* 8 bytes */
#define TEST_AS_TYPE_8(DST, N)           \
  TEST_AS_TYPE(DST, N, char8, 8)         \
  TEST_AS_TYPE(DST, N, uchar8, 8)        \
  TEST_AS_TYPE(DST, N, short4, 8)        \
  TEST_AS_TYPE(DST, N, ushort4, 8)       \
  TEST_AS_TYPE(DST, N, short3, 6)        \
  TEST_AS_TYPE(DST, N, ushort3, 6)       \
  TEST_AS_TYPE(DST, N, int2, 8)          \
  TEST_AS_TYPE(DST, N, uint2, 8)         \
  __IF_INT64(                            \
  TEST_AS_TYPE(DST, N, long, 8)          \
  TEST_AS_TYPE(DST, N, ulong, 8))        \
  TEST_AS_TYPE(DST, N, float2, 8)        \
  __IF_FP64(                             \
  TEST_AS_TYPE(DST, N, double, 8))

  TEST_AS_TYPE_8(char8, 8)
  TEST_AS_TYPE_8(uchar8, 8)
  TEST_AS_TYPE_8(short4, 8)
  TEST_AS_TYPE_8(ushort4, 8)
  TEST_AS_TYPE_8(short3, 6)
  TEST_AS_TYPE_8(ushort3, 6)
  TEST_AS_TYPE_8(int2, 8)
  TEST_AS_TYPE_8(uint2, 8)
  __IF_INT64(
  TEST_AS_TYPE_8(long, 8)
  TEST_AS_TYPE_8(ulong, 8))
  TEST_AS_TYPE_8(float2, 8)
  __IF_FP64(
  TEST_AS_TYPE_8(double, 8))

/* 16 bytes */
#define TEST_AS_TYPE_16(DST, N)          \
  TEST_AS_TYPE(DST, N, char16, 16)       \
  TEST_AS_TYPE(DST, N, uchar16, 16)      \
  TEST_AS_TYPE(DST, N, short8, 16)       \
  TEST_AS_TYPE(DST, N, ushort8, 16)      \
  TEST_AS_TYPE(DST, N, int4, 16)         \
  TEST_AS_TYPE(DST, N, uint4, 16)        \
  TEST_AS_TYPE(DST, N, int3, 12)         \
  TEST_AS_TYPE(DST, N, uint3, 12)        \
  __IF_INT64(                            \
  TEST_AS_TYPE(DST, N, long2, 16)        \
  TEST_AS_TYPE(DST, N, ulong2, 16))      \
  TEST_AS_TYPE(DST, N, float4, 16)       \
  TEST_AS_TYPE(DST, N, float3, 12)       \
  __IF_FP64(                             \
  TEST_AS_TYPE(DST, N, double2, 16))

  TEST_AS_TYPE_16(char16, 16)
  TEST_AS_TYPE_16(uchar16, 16)
  TEST_AS_TYPE_16(short8, 16)
  TEST_AS_TYPE_16(ushort8, 16)
  TEST_AS_TYPE_16(int4, 16)
  TEST_AS_TYPE_16(uint4, 16)
  TEST_AS_TYPE_16(int3, 12)
  TEST_AS_TYPE_16(uint3, 12)
  __IF_INT64(
  TEST_AS_TYPE_16(long2, 16)
  TEST_AS_TYPE_16(ulong2, 16))
  TEST_AS_TYPE_16(float4, 16)
  TEST_AS_TYPE_16(float3, 12)
  __IF_FP64(
  TEST_AS_TYPE_16(double2, 16))

/* 32 bytes */
#define TEST_AS_TYPE_32(DST, N)           \
  TEST_AS_TYPE(DST, N, short16, 32)       \
  TEST_AS_TYPE(DST, N, ushort16, 32)      \
  TEST_AS_TYPE(DST, N, int8, 32)          \
  TEST_AS_TYPE(DST, N, uint8, 32)         \
  __IF_INT64(                             \
  TEST_AS_TYPE(DST, N, long4, 32)         \
  TEST_AS_TYPE(DST, N, ulong4, 32)        \
  TEST_AS_TYPE(DST, N, long3, 24)         \
  TEST_AS_TYPE(DST, N, ulong3, 24))       \
  TEST_AS_TYPE(DST, N, float8, 32)        \
  __IF_FP64(                              \
  TEST_AS_TYPE(DST, N, double4, 32)       \
  TEST_AS_TYPE(DST, N, double3, 24))

  TEST_AS_TYPE_32(short16, 32)
  TEST_AS_TYPE_32(ushort16, 32)
  TEST_AS_TYPE_32(int8, 32)
  TEST_AS_TYPE_32(uint8, 32)
  __IF_INT64(
  TEST_AS_TYPE_32(long4, 32)
  TEST_AS_TYPE_32(ulong4, 32)
  TEST_AS_TYPE_32(long3, 24)
  TEST_AS_TYPE_32(ulong3, 24))
  TEST_AS_TYPE_32(float8, 32)
  __IF_FP64(
  TEST_AS_TYPE_32(double4, 32)
  TEST_AS_TYPE_32(double3, 24))

/* 64 bytes */
#define TEST_AS_TYPE_64(DST)              \
  TEST_AS_TYPE(DST, 64, int16, 64)        \
  TEST_AS_TYPE(DST, 64, uint16, 64)       \
  __IF_INT64(                             \
  TEST_AS_TYPE(DST, 64, long8, 64)        \
  TEST_AS_TYPE(DST, 64, ulong8, 64))      \
  TEST_AS_TYPE(DST, 64, float16, 64)      \
  __IF_FP64(                              \
  TEST_AS_TYPE(DST, 64, double8, 64))

  TEST_AS_TYPE_64(int16)
  TEST_AS_TYPE_64(uint16)
  __IF_INT64(
  TEST_AS_TYPE_64(long8)
  TEST_AS_TYPE_64(ulong8))
  TEST_AS_TYPE_64(float16)
  __IF_FP64(
  TEST_AS_TYPE_64(double8))

/* 128 bytes */
#define TEST_AS_TYPE_128(DST, N)          \
  __IF_INT64(                             \
  TEST_AS_TYPE(DST, N, long16, 128)       \
  TEST_AS_TYPE(DST, N, ulong16, 128))     \
  __IF_FP64(                              \
  TEST_AS_TYPE(DST, N, double16, 128))

  __IF_INT64(
  TEST_AS_TYPE_128(long16, 128)
  TEST_AS_TYPE_128(ulong16, 128))
  __IF_FP64(
  TEST_AS_TYPE_128(double16, 128))
}