dispatcher.cc revision 13345
19793Sakash.bagdia@arm.com/*
29518SAndreas.Sandberg@ARM.com * Copyright (c) 2011-2015,2018 Advanced Micro Devices, Inc.
39518SAndreas.Sandberg@ARM.com * All rights reserved.
49518SAndreas.Sandberg@ARM.com *
59518SAndreas.Sandberg@ARM.com * For use for simulation and test purposes only
69518SAndreas.Sandberg@ARM.com *
79518SAndreas.Sandberg@ARM.com * Redistribution and use in source and binary forms, with or without
89518SAndreas.Sandberg@ARM.com * modification, are permitted provided that the following conditions are met:
99518SAndreas.Sandberg@ARM.com *
109518SAndreas.Sandberg@ARM.com * 1. Redistributions of source code must retain the above copyright notice,
119518SAndreas.Sandberg@ARM.com * this list of conditions and the following disclaimer.
129518SAndreas.Sandberg@ARM.com *
135347Ssaidi@eecs.umich.edu * 2. Redistributions in binary form must reproduce the above copyright notice,
147534Ssteve.reinhardt@amd.com * this list of conditions and the following disclaimer in the documentation
153395Shsul@eecs.umich.edu * and/or other materials provided with the distribution.
163395Shsul@eecs.umich.edu *
173395Shsul@eecs.umich.edu * 3. Neither the name of the copyright holder nor the names of its
183395Shsul@eecs.umich.edu * contributors may be used to endorse or promote products derived from this
193395Shsul@eecs.umich.edu * software without specific prior written permission.
203395Shsul@eecs.umich.edu *
213395Shsul@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
223395Shsul@eecs.umich.edu * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
233395Shsul@eecs.umich.edu * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
243395Shsul@eecs.umich.edu * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
253395Shsul@eecs.umich.edu * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
263395Shsul@eecs.umich.edu * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
273395Shsul@eecs.umich.edu * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
283395Shsul@eecs.umich.edu * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
293395Shsul@eecs.umich.edu * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
303395Shsul@eecs.umich.edu * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
313395Shsul@eecs.umich.edu * POSSIBILITY OF SUCH DAMAGE.
323395Shsul@eecs.umich.edu *
333395Shsul@eecs.umich.edu * Authors: Brad Beckmann,
343395Shsul@eecs.umich.edu *          Marc Orr,
353395Shsul@eecs.umich.edu *          Anthony Gutierrez
363395Shsul@eecs.umich.edu */
373395Shsul@eecs.umich.edu
383395Shsul@eecs.umich.edu
393395Shsul@eecs.umich.edu#include "gpu-compute/dispatcher.hh"
403395Shsul@eecs.umich.edu
413395Shsul@eecs.umich.edu#include "cpu/base.hh"
429457Svilanova@ac.upc.edu#include "debug/GPUDisp.hh"
433395Shsul@eecs.umich.edu#include "gpu-compute/cl_driver.hh"
443509Shsul@eecs.umich.edu#include "gpu-compute/cl_event.hh"
456654Snate@binkert.org#include "gpu-compute/shader.hh"
469520SAndreas.Sandberg@ARM.com#include "gpu-compute/wavefront.hh"
479665Sandreas.hansson@arm.com#include "mem/packet_access.hh"
489520SAndreas.Sandberg@ARM.com
493395Shsul@eecs.umich.eduGpuDispatcher *GpuDispatcher::instance = nullptr;
506654Snate@binkert.org
513395Shsul@eecs.umich.eduGpuDispatcher::GpuDispatcher(const Params *p)
526654Snate@binkert.org    : DmaDevice(p), _masterId(p->system->getMasterId(this, "disp")),
536654Snate@binkert.org      pioAddr(p->pio_addr), pioSize(4096), pioDelay(p->pio_latency),
546654Snate@binkert.org      dispatchCount(0), dispatchActive(false), cpu(p->cpu),
553395Shsul@eecs.umich.edu      shader(p->shader_pointer), driver(p->cl_driver),
569139Snilay@cs.wisc.edu      tickEvent([this]{ exec(); }, "GPU Dispatcher tick",
579520SAndreas.Sandberg@ARM.com                false, Event::CPU_Tick_Pri)
589520SAndreas.Sandberg@ARM.com{
599520SAndreas.Sandberg@ARM.com    shader->handshake(this);
609139Snilay@cs.wisc.edu    driver->handshake(this);
613481Shsul@eecs.umich.edu
629139Snilay@cs.wisc.edu    ndRange.wg_disp_rem = false;
633481Shsul@eecs.umich.edu    ndRange.globalWgId = 0;
649139Snilay@cs.wisc.edu
659139Snilay@cs.wisc.edu    schedule(&tickEvent, 0);
669139Snilay@cs.wisc.edu
679139Snilay@cs.wisc.edu    // translation port for the dispatcher
689139Snilay@cs.wisc.edu    tlbPort = new TLBPort(csprintf("%s-port%d", name()), this);
699139Snilay@cs.wisc.edu
709139Snilay@cs.wisc.edu    num_kernelLaunched
719139Snilay@cs.wisc.edu    .name(name() + ".num_kernel_launched")
723481Shsul@eecs.umich.edu    .desc("number of kernel launched")
739518SAndreas.Sandberg@ARM.com    ;
749518SAndreas.Sandberg@ARM.com}
759518SAndreas.Sandberg@ARM.com
763481Shsul@eecs.umich.eduGpuDispatcher *GpuDispatcherParams::create()
779139Snilay@cs.wisc.edu{
789139Snilay@cs.wisc.edu    GpuDispatcher *dispatcher = new GpuDispatcher(this);
793481Shsul@eecs.umich.edu    GpuDispatcher::setInstance(dispatcher);
809139Snilay@cs.wisc.edu
819139Snilay@cs.wisc.edu    return GpuDispatcher::getInstance();
829139Snilay@cs.wisc.edu}
839139Snilay@cs.wisc.edu
849139Snilay@cs.wisc.eduvoid
853481Shsul@eecs.umich.eduGpuDispatcher::serialize(CheckpointOut &cp) const
863481Shsul@eecs.umich.edu{
873481Shsul@eecs.umich.edu    Tick event_tick = 0;
889665Sandreas.hansson@arm.com
899665Sandreas.hansson@arm.com    if (ndRange.wg_disp_rem)
909665Sandreas.hansson@arm.com        fatal("Checkpointing not supported during active workgroup execution");
919665Sandreas.hansson@arm.com
929665Sandreas.hansson@arm.com    if (tickEvent.scheduled())
938919Snilay@cs.wisc.edu        event_tick = tickEvent.when();
948919Snilay@cs.wisc.edu
958919Snilay@cs.wisc.edu    SERIALIZE_SCALAR(event_tick);
968919Snilay@cs.wisc.edu
978919Snilay@cs.wisc.edu}
988919Snilay@cs.wisc.edu
998919Snilay@cs.wisc.eduvoid
1008919Snilay@cs.wisc.eduGpuDispatcher::unserialize(CheckpointIn &cp)
1018919Snilay@cs.wisc.edu{
1028919Snilay@cs.wisc.edu    Tick event_tick;
1038919Snilay@cs.wisc.edu
1048919Snilay@cs.wisc.edu    if (tickEvent.scheduled())
1058919Snilay@cs.wisc.edu        deschedule(&tickEvent);
1068919Snilay@cs.wisc.edu
1078919Snilay@cs.wisc.edu    UNSERIALIZE_SCALAR(event_tick);
1083481Shsul@eecs.umich.edu
1099140Snilay@cs.wisc.edu    if (event_tick)
1109140Snilay@cs.wisc.edu        schedule(&tickEvent, event_tick);
1119140Snilay@cs.wisc.edu}
1129140Snilay@cs.wisc.edu
1139140Snilay@cs.wisc.eduAddrRangeList
1149140Snilay@cs.wisc.eduGpuDispatcher::getAddrRanges() const
1159140Snilay@cs.wisc.edu{
1169140Snilay@cs.wisc.edu    AddrRangeList ranges;
1179140Snilay@cs.wisc.edu
1189140Snilay@cs.wisc.edu    DPRINTF(GPUDisp, "dispatcher registering addr range at %#x size %#x\n",
1199140Snilay@cs.wisc.edu            pioAddr, pioSize);
1209140Snilay@cs.wisc.edu
1219140Snilay@cs.wisc.edu    ranges.push_back(RangeSize(pioAddr, pioSize));
1229140Snilay@cs.wisc.edu
1239140Snilay@cs.wisc.edu    return ranges;
1249140Snilay@cs.wisc.edu}
1259140Snilay@cs.wisc.edu
1269140Snilay@cs.wisc.eduTick
1279140Snilay@cs.wisc.eduGpuDispatcher::read(PacketPtr pkt)
1289140Snilay@cs.wisc.edu{
1299140Snilay@cs.wisc.edu    assert(pkt->getAddr() >= pioAddr);
1309140Snilay@cs.wisc.edu    assert(pkt->getAddr() < pioAddr + pioSize);
1319140Snilay@cs.wisc.edu
1329140Snilay@cs.wisc.edu    int offset = pkt->getAddr() - pioAddr;
1339140Snilay@cs.wisc.edu    pkt->allocate();
1349140Snilay@cs.wisc.edu
1359140Snilay@cs.wisc.edu    DPRINTF(GPUDisp, " read register %#x size=%d\n", offset, pkt->getSize());
1369140Snilay@cs.wisc.edu
1379140Snilay@cs.wisc.edu    if (offset < 8) {
1389140Snilay@cs.wisc.edu        assert(!offset);
1399140Snilay@cs.wisc.edu        assert(pkt->getSize() == 8);
1409140Snilay@cs.wisc.edu
1419140Snilay@cs.wisc.edu        uint64_t retval = dispatchActive;
1429140Snilay@cs.wisc.edu        pkt->setLE(retval);
1439140Snilay@cs.wisc.edu    } else {
1449140Snilay@cs.wisc.edu        offset -= 8;
1459140Snilay@cs.wisc.edu        assert(offset + pkt->getSize() < sizeof(HsaQueueEntry));
1469140Snilay@cs.wisc.edu        char *curTaskPtr = (char*)&curTask;
1479140Snilay@cs.wisc.edu
1489140Snilay@cs.wisc.edu        memcpy(pkt->getPtr<const void*>(), curTaskPtr + offset, pkt->getSize());
1499140Snilay@cs.wisc.edu    }
1509140Snilay@cs.wisc.edu
1519140Snilay@cs.wisc.edu    pkt->makeAtomicResponse();
1529140Snilay@cs.wisc.edu
1539140Snilay@cs.wisc.edu    return pioDelay;
1549140Snilay@cs.wisc.edu}
1559140Snilay@cs.wisc.edu
1569140Snilay@cs.wisc.eduTick
1579140Snilay@cs.wisc.eduGpuDispatcher::write(PacketPtr pkt)
1589140Snilay@cs.wisc.edu{
1599140Snilay@cs.wisc.edu    assert(pkt->getAddr() >= pioAddr);
1609140Snilay@cs.wisc.edu    assert(pkt->getAddr() < pioAddr + pioSize);
1619140Snilay@cs.wisc.edu
1629140Snilay@cs.wisc.edu    int offset = pkt->getAddr() - pioAddr;
1639215Sandreas.hansson@arm.com
1649140Snilay@cs.wisc.edu#if TRACING_ON
1659140Snilay@cs.wisc.edu    uint64_t data_val = 0;
1669140Snilay@cs.wisc.edu
1679140Snilay@cs.wisc.edu    switch (pkt->getSize()) {
1689140Snilay@cs.wisc.edu      case 1:
1699140Snilay@cs.wisc.edu        data_val = pkt->getLE<uint8_t>();
1709140Snilay@cs.wisc.edu        break;
1719140Snilay@cs.wisc.edu      case 2:
1729140Snilay@cs.wisc.edu        data_val = pkt->getLE<uint16_t>();
1739140Snilay@cs.wisc.edu        break;
1749140Snilay@cs.wisc.edu      case 4:
1759140Snilay@cs.wisc.edu        data_val = pkt->getLE<uint32_t>();
1769140Snilay@cs.wisc.edu        break;
1779140Snilay@cs.wisc.edu      case 8:
1789140Snilay@cs.wisc.edu        data_val = pkt->getLE<uint64_t>();
1799140Snilay@cs.wisc.edu        break;
1809140Snilay@cs.wisc.edu      default:
1819140Snilay@cs.wisc.edu        DPRINTF(GPUDisp, "bad size %d\n", pkt->getSize());
1829140Snilay@cs.wisc.edu    }
1839140Snilay@cs.wisc.edu
1849140Snilay@cs.wisc.edu    DPRINTF(GPUDisp, "write register %#x value %#x size=%d\n", offset, data_val,
1859140Snilay@cs.wisc.edu            pkt->getSize());
1869140Snilay@cs.wisc.edu#endif
1879140Snilay@cs.wisc.edu    if (!offset) {
1889140Snilay@cs.wisc.edu        static int nextId = 0;
1899140Snilay@cs.wisc.edu
1909156Sandreas.hansson@arm.com        // The depends field of the qstruct, which was previously unused, is
1919140Snilay@cs.wisc.edu        // used to communicate with simulated application.
1929634Sjthestness@gmail.com        if (curTask.depends) {
1939140Snilay@cs.wisc.edu            HostState hs;
1949140Snilay@cs.wisc.edu            shader->ReadMem((uint64_t)(curTask.depends), &hs,
1959140Snilay@cs.wisc.edu                            sizeof(HostState), 0);
1969140Snilay@cs.wisc.edu
1979140Snilay@cs.wisc.edu            // update event start time (in nano-seconds)
1989140Snilay@cs.wisc.edu            uint64_t start = curTick() / 1000;
1999140Snilay@cs.wisc.edu
2009140Snilay@cs.wisc.edu            shader->WriteMem((uint64_t)(&((_cl_event*)hs.event)->start),
2019140Snilay@cs.wisc.edu                             &start, sizeof(uint64_t), 0);
2029140Snilay@cs.wisc.edu        }
2039140Snilay@cs.wisc.edu
2049140Snilay@cs.wisc.edu        // launch kernel
2059140Snilay@cs.wisc.edu        ++num_kernelLaunched;
2069140Snilay@cs.wisc.edu
2079140Snilay@cs.wisc.edu        NDRange *ndr = &(ndRangeMap[nextId]);
2089140Snilay@cs.wisc.edu        // copy dispatch info
2099140Snilay@cs.wisc.edu        ndr->q = curTask;
2109140Snilay@cs.wisc.edu
2119140Snilay@cs.wisc.edu        // update the numDispTask polled by the runtime
2129140Snilay@cs.wisc.edu        accessUserVar(cpu, (uint64_t)(curTask.numDispLeft), 0, 1);
2139140Snilay@cs.wisc.edu
2149140Snilay@cs.wisc.edu        ndr->numWgTotal = 1;
2159140Snilay@cs.wisc.edu
2169140Snilay@cs.wisc.edu        for (int i = 0; i < 3; ++i) {
2179140Snilay@cs.wisc.edu            ndr->wgId[i] = 0;
2189140Snilay@cs.wisc.edu            ndr->numWg[i] = divCeil(curTask.gdSize[i], curTask.wgSize[i]);
2199140Snilay@cs.wisc.edu            ndr->numWgTotal *= ndr->numWg[i];
2209140Snilay@cs.wisc.edu        }
2219606Snilay@cs.wisc.edu
2229140Snilay@cs.wisc.edu        ndr->numWgCompleted = 0;
2239140Snilay@cs.wisc.edu        ndr->globalWgId = 0;
2249634Sjthestness@gmail.com        ndr->wg_disp_rem = true;
2259140Snilay@cs.wisc.edu        ndr->execDone = false;
2269140Snilay@cs.wisc.edu        ndr->addrToNotify = (volatile bool*)curTask.addrToNotify;
2279140Snilay@cs.wisc.edu        ndr->numDispLeft = (volatile uint32_t*)curTask.numDispLeft;
2289140Snilay@cs.wisc.edu        ndr->dispatchId = nextId;
2299140Snilay@cs.wisc.edu        ndr->curCid = pkt->req->contextId();
2309140Snilay@cs.wisc.edu        DPRINTF(GPUDisp, "launching kernel %d\n",nextId);
2319140Snilay@cs.wisc.edu        execIds.push(nextId);
2329140Snilay@cs.wisc.edu        ++nextId;
2339140Snilay@cs.wisc.edu
2349140Snilay@cs.wisc.edu        dispatchActive = true;
2359140Snilay@cs.wisc.edu
2369140Snilay@cs.wisc.edu        if (!tickEvent.scheduled()) {
2379140Snilay@cs.wisc.edu            schedule(&tickEvent, curTick() + shader->ticks(1));
2389140Snilay@cs.wisc.edu        }
2399140Snilay@cs.wisc.edu    } else {
2409460Ssaidi@eecs.umich.edu        // populate current task struct
2419140Snilay@cs.wisc.edu        // first 64 bits are launch reg
2429151Satgutier@umich.edu        offset -= 8;
2439151Satgutier@umich.edu        assert(offset < sizeof(HsaQueueEntry));
2449151Satgutier@umich.edu        char *curTaskPtr = (char*)&curTask;
2459151Satgutier@umich.edu        memcpy(curTaskPtr + offset, pkt->getPtr<const void*>(), pkt->getSize());
2469151Satgutier@umich.edu    }
2479151Satgutier@umich.edu
2489151Satgutier@umich.edu    pkt->makeAtomicResponse();
2499460Ssaidi@eecs.umich.edu
2509151Satgutier@umich.edu    return pioDelay;
2519521SAndreas.Sandberg@ARM.com}
2529151Satgutier@umich.edu
2539151Satgutier@umich.edu
2549151Satgutier@umich.eduBaseMasterPort&
2559151Satgutier@umich.eduGpuDispatcher::getMasterPort(const std::string &if_name, PortID idx)
2569151Satgutier@umich.edu{
2579151Satgutier@umich.edu    if (if_name == "translation_port") {
2589151Satgutier@umich.edu        return *tlbPort;
2599151Satgutier@umich.edu    }
2609460Ssaidi@eecs.umich.edu
2619151Satgutier@umich.edu    return DmaDevice::getMasterPort(if_name, idx);
2623481Shsul@eecs.umich.edu}
2633395Shsul@eecs.umich.edu
2643395Shsul@eecs.umich.eduvoid
2653395Shsul@eecs.umich.eduGpuDispatcher::exec()
2664167Sbinkertn@umich.edu{
2673395Shsul@eecs.umich.edu    int fail_count = 0;
2683395Shsul@eecs.umich.edu
2693395Shsul@eecs.umich.edu    // There are potentially multiple outstanding kernel launches.
2703511Shsul@eecs.umich.edu    // It is possible that the workgroups in a different kernel
2713395Shsul@eecs.umich.edu    // can fit on the GPU even if another kernel's workgroups cannot
2723395Shsul@eecs.umich.edu    DPRINTF(GPUDisp, "Launching %d Kernels\n", execIds.size());
2733395Shsul@eecs.umich.edu
2745211Ssaidi@eecs.umich.edu    while (execIds.size() > fail_count) {
2755211Ssaidi@eecs.umich.edu        int execId = execIds.front();
2763395Shsul@eecs.umich.edu
2773395Shsul@eecs.umich.edu        while (ndRangeMap[execId].wg_disp_rem) {
2783395Shsul@eecs.umich.edu            //update the thread context
2795370Ssaidi@eecs.umich.edu            shader->updateContext(ndRangeMap[execId].curCid);
2806654Snate@binkert.org
2815370Ssaidi@eecs.umich.edu            // attempt to dispatch_workgroup
2825371Shsul@eecs.umich.edu            if (!shader->dispatch_workgroups(&ndRangeMap[execId])) {
2836654Snate@binkert.org                // if we failed try the next kernel,
2845370Ssaidi@eecs.umich.edu                // it may have smaller workgroups.
2859151Satgutier@umich.edu                // put it on the queue to rety latter
2869151Satgutier@umich.edu                DPRINTF(GPUDisp, "kernel %d failed to launch\n", execId);
2879151Satgutier@umich.edu                execIds.push(execId);
2889151Satgutier@umich.edu                ++fail_count;
2899151Satgutier@umich.edu                break;
2909151Satgutier@umich.edu            }
2913395Shsul@eecs.umich.edu        }
2923481Shsul@eecs.umich.edu        // let's try the next kernel_id
2933481Shsul@eecs.umich.edu        execIds.pop();
2948318Sksewell@umich.edu    }
2956144Sksewell@umich.edu
2968311Sksewell@umich.edu    DPRINTF(GPUDisp, "Returning %d Kernels\n", doneIds.size());
2976144Sksewell@umich.edu
2986641Sksewell@umich.edu    if (doneIds.size() && cpu) {
2996641Sksewell@umich.edu        shader->hostWakeUp(cpu);
3006641Sksewell@umich.edu    }
3016641Sksewell@umich.edu
3023481Shsul@eecs.umich.edu    while (doneIds.size()) {
3039433SAndreas.Sandberg@ARM.com        // wakeup the CPU if any Kernels completed this cycle
3043481Shsul@eecs.umich.edu        DPRINTF(GPUDisp, "WorkGroup %d completed\n", doneIds.front());
3053481Shsul@eecs.umich.edu        doneIds.pop();
3063481Shsul@eecs.umich.edu    }
3075361Srstrong@cs.ucsd.edu}
3085369Ssaidi@eecs.umich.edu
3093481Shsul@eecs.umich.eduvoid
3108803Sgblack@eecs.umich.eduGpuDispatcher::notifyWgCompl(Wavefront *w)
3119793Sakash.bagdia@arm.com{
3125369Ssaidi@eecs.umich.edu    int kern_id = w->kernId;
3138311Sksewell@umich.edu    DPRINTF(GPUDisp, "notify WgCompl %d\n",kern_id);
3148311Sksewell@umich.edu    assert(ndRangeMap[kern_id].dispatchId == kern_id);
3158887Sgeoffrey.blake@arm.com    ndRangeMap[kern_id].numWgCompleted++;
3168887Sgeoffrey.blake@arm.com
3178887Sgeoffrey.blake@arm.com    if (ndRangeMap[kern_id].numWgCompleted == ndRangeMap[kern_id].numWgTotal) {
3183481Shsul@eecs.umich.edu        ndRangeMap[kern_id].execDone = true;
3195311Ssaidi@eecs.umich.edu        doneIds.push(kern_id);
3203481Shsul@eecs.umich.edu
3213395Shsul@eecs.umich.edu        if (ndRangeMap[kern_id].addrToNotify) {
3229151Satgutier@umich.edu            accessUserVar(cpu, (uint64_t)(ndRangeMap[kern_id].addrToNotify), 1,
3239518SAndreas.Sandberg@ARM.com                          0);
3249518SAndreas.Sandberg@ARM.com        }
3259518SAndreas.Sandberg@ARM.com
3269518SAndreas.Sandberg@ARM.com        accessUserVar(cpu, (uint64_t)(ndRangeMap[kern_id].numDispLeft), 0, -1);
3279518SAndreas.Sandberg@ARM.com
3289518SAndreas.Sandberg@ARM.com        // update event end time (in nano-seconds)
3299518SAndreas.Sandberg@ARM.com        if (ndRangeMap[kern_id].q.depends) {
3309518SAndreas.Sandberg@ARM.com            HostState *host_state = (HostState*)ndRangeMap[kern_id].q.depends;
3319151Satgutier@umich.edu            uint64_t event;
3329518SAndreas.Sandberg@ARM.com            shader->ReadMem((uint64_t)(&host_state->event), &event,
3339518SAndreas.Sandberg@ARM.com                            sizeof(uint64_t), 0);
3349151Satgutier@umich.edu
3359151Satgutier@umich.edu            uint64_t end = curTick() / 1000;
3369151Satgutier@umich.edu
3379151Satgutier@umich.edu            shader->WriteMem((uint64_t)(&((_cl_event*)event)->end), &end,
3389793Sakash.bagdia@arm.com                             sizeof(uint64_t), 0);
3399151Satgutier@umich.edu        }
3409151Satgutier@umich.edu    }
3419151Satgutier@umich.edu
3429151Satgutier@umich.edu    if (!tickEvent.scheduled()) {
3439151Satgutier@umich.edu        schedule(&tickEvent, curTick() + shader->ticks(1));
3449151Satgutier@umich.edu    }
3459151Satgutier@umich.edu}
3469151Satgutier@umich.edu
3479151Satgutier@umich.eduvoid
3489151Satgutier@umich.eduGpuDispatcher::scheduleDispatch()
3499151Satgutier@umich.edu{
3509151Satgutier@umich.edu    if (!tickEvent.scheduled())
3519151Satgutier@umich.edu        schedule(&tickEvent, curTick() + shader->ticks(1));
3529151Satgutier@umich.edu}
3539151Satgutier@umich.edu
3549151Satgutier@umich.eduvoid
3553395Shsul@eecs.umich.eduGpuDispatcher::accessUserVar(BaseCPU *cpu, uint64_t addr, int val, int off)
3569433SAndreas.Sandberg@ARM.com{
3573395Shsul@eecs.umich.edu    if (cpu) {
3589433SAndreas.Sandberg@ARM.com        if (off) {
3593395Shsul@eecs.umich.edu            shader->AccessMem(addr, &val, sizeof(int), 0, MemCmd::ReadReq,
3603478Shsul@eecs.umich.edu                              true);
3613395Shsul@eecs.umich.edu            val += off;
3623395Shsul@eecs.umich.edu        }
3633478Shsul@eecs.umich.edu
3648803Sgblack@eecs.umich.edu        shader->AccessMem(addr, &val, sizeof(int), 0, MemCmd::WriteReq, true);
3658803Sgblack@eecs.umich.edu    } else {
3669793Sakash.bagdia@arm.com        panic("Cannot find host");
3679793Sakash.bagdia@arm.com    }
3683480Shsul@eecs.umich.edu}
3695361Srstrong@cs.ucsd.edu
3705369Ssaidi@eecs.umich.edu// helper functions for driver to retrieve GPU attributes
3715361Srstrong@cs.ucsd.eduint
3725361Srstrong@cs.ucsd.eduGpuDispatcher::getNumCUs()
3735361Srstrong@cs.ucsd.edu{
3745369Ssaidi@eecs.umich.edu    return shader->cuList.size();
3755361Srstrong@cs.ucsd.edu}
3765361Srstrong@cs.ucsd.edu
3775378Ssaidi@eecs.umich.eduint
3786654Snate@binkert.orgGpuDispatcher::wfSize() const
3795361Srstrong@cs.ucsd.edu{
3805361Srstrong@cs.ucsd.edu    return shader->cuList[0]->wfSize();
3815361Srstrong@cs.ucsd.edu}
3825361Srstrong@cs.ucsd.edu
3835361Srstrong@cs.ucsd.eduvoid
3845361Srstrong@cs.ucsd.eduGpuDispatcher::setFuncargsSize(int funcargs_size)
3855361Srstrong@cs.ucsd.edu{
3865361Srstrong@cs.ucsd.edu    shader->funcargs_size = funcargs_size;
3875361Srstrong@cs.ucsd.edu}
3885361Srstrong@cs.ucsd.edu
3895361Srstrong@cs.ucsd.eduuint32_t
3908311Sksewell@umich.eduGpuDispatcher::getStaticContextSize() const
3918311Sksewell@umich.edu{
3925353Svilas.sridharan@gmail.com    return shader->cuList[0]->wfList[0][0]->getStaticContextSize();
3938887Sgeoffrey.blake@arm.com}
3948887Sgeoffrey.blake@arm.com