111308Santhony.gutierrez@amd.com/* 212697Santhony.gutierrez@amd.com * Copyright (c) 2011-2015,2018 Advanced Micro Devices, Inc. 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only 611308Santhony.gutierrez@amd.com * 711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met: 911308Santhony.gutierrez@amd.com * 1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer. 1211308Santhony.gutierrez@amd.com * 1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation 1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution. 1611308Santhony.gutierrez@amd.com * 1712697Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its 1812697Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from this 1912697Santhony.gutierrez@amd.com * software without specific prior written permission. 2011308Santhony.gutierrez@amd.com * 2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211308Santhony.gutierrez@amd.com * 3312697Santhony.gutierrez@amd.com * Authors: Brad Beckmann, 3412697Santhony.gutierrez@amd.com * Marc Orr, 3512697Santhony.gutierrez@amd.com * Anthony Gutierrez 3611308Santhony.gutierrez@amd.com */ 3711308Santhony.gutierrez@amd.com 3811308Santhony.gutierrez@amd.com 3911308Santhony.gutierrez@amd.com#include "gpu-compute/dispatcher.hh" 4011308Santhony.gutierrez@amd.com 4111308Santhony.gutierrez@amd.com#include "cpu/base.hh" 4211308Santhony.gutierrez@amd.com#include "debug/GPUDisp.hh" 4311308Santhony.gutierrez@amd.com#include "gpu-compute/cl_driver.hh" 4411308Santhony.gutierrez@amd.com#include "gpu-compute/cl_event.hh" 4511308Santhony.gutierrez@amd.com#include "gpu-compute/shader.hh" 4611308Santhony.gutierrez@amd.com#include "gpu-compute/wavefront.hh" 4711308Santhony.gutierrez@amd.com#include "mem/packet_access.hh" 4811308Santhony.gutierrez@amd.com 4911308Santhony.gutierrez@amd.comGpuDispatcher *GpuDispatcher::instance = nullptr; 5011308Santhony.gutierrez@amd.com 5111308Santhony.gutierrez@amd.comGpuDispatcher::GpuDispatcher(const Params *p) 5212680Sgiacomo.travaglini@arm.com : DmaDevice(p), _masterId(p->system->getMasterId(this, "disp")), 5311308Santhony.gutierrez@amd.com pioAddr(p->pio_addr), pioSize(4096), pioDelay(p->pio_latency), 5411308Santhony.gutierrez@amd.com dispatchCount(0), dispatchActive(false), cpu(p->cpu), 5512126Sspwilson2@wisc.edu shader(p->shader_pointer), driver(p->cl_driver), 5612126Sspwilson2@wisc.edu tickEvent([this]{ exec(); }, "GPU Dispatcher tick", 5712126Sspwilson2@wisc.edu false, Event::CPU_Tick_Pri) 5811308Santhony.gutierrez@amd.com{ 5911308Santhony.gutierrez@amd.com shader->handshake(this); 6011308Santhony.gutierrez@amd.com driver->handshake(this); 6111308Santhony.gutierrez@amd.com 6211308Santhony.gutierrez@amd.com ndRange.wg_disp_rem = false; 6311308Santhony.gutierrez@amd.com ndRange.globalWgId = 0; 6411308Santhony.gutierrez@amd.com 6511308Santhony.gutierrez@amd.com schedule(&tickEvent, 0); 6611308Santhony.gutierrez@amd.com 6711308Santhony.gutierrez@amd.com // translation port for the dispatcher 6811308Santhony.gutierrez@amd.com tlbPort = new TLBPort(csprintf("%s-port%d", name()), this); 6911308Santhony.gutierrez@amd.com 7011308Santhony.gutierrez@amd.com num_kernelLaunched 7111308Santhony.gutierrez@amd.com .name(name() + ".num_kernel_launched") 7211308Santhony.gutierrez@amd.com .desc("number of kernel launched") 7311308Santhony.gutierrez@amd.com ; 7411308Santhony.gutierrez@amd.com} 7511308Santhony.gutierrez@amd.com 7611308Santhony.gutierrez@amd.comGpuDispatcher *GpuDispatcherParams::create() 7711308Santhony.gutierrez@amd.com{ 7811308Santhony.gutierrez@amd.com GpuDispatcher *dispatcher = new GpuDispatcher(this); 7911308Santhony.gutierrez@amd.com GpuDispatcher::setInstance(dispatcher); 8011308Santhony.gutierrez@amd.com 8111308Santhony.gutierrez@amd.com return GpuDispatcher::getInstance(); 8211308Santhony.gutierrez@amd.com} 8311308Santhony.gutierrez@amd.com 8411308Santhony.gutierrez@amd.comvoid 8511308Santhony.gutierrez@amd.comGpuDispatcher::serialize(CheckpointOut &cp) const 8611308Santhony.gutierrez@amd.com{ 8711308Santhony.gutierrez@amd.com Tick event_tick = 0; 8811308Santhony.gutierrez@amd.com 8911308Santhony.gutierrez@amd.com if (ndRange.wg_disp_rem) 9011308Santhony.gutierrez@amd.com fatal("Checkpointing not supported during active workgroup execution"); 9111308Santhony.gutierrez@amd.com 9211308Santhony.gutierrez@amd.com if (tickEvent.scheduled()) 9311308Santhony.gutierrez@amd.com event_tick = tickEvent.when(); 9411308Santhony.gutierrez@amd.com 9511308Santhony.gutierrez@amd.com SERIALIZE_SCALAR(event_tick); 9611308Santhony.gutierrez@amd.com 9711308Santhony.gutierrez@amd.com} 9811308Santhony.gutierrez@amd.com 9911308Santhony.gutierrez@amd.comvoid 10011308Santhony.gutierrez@amd.comGpuDispatcher::unserialize(CheckpointIn &cp) 10111308Santhony.gutierrez@amd.com{ 10211308Santhony.gutierrez@amd.com Tick event_tick; 10311308Santhony.gutierrez@amd.com 10411308Santhony.gutierrez@amd.com if (tickEvent.scheduled()) 10511308Santhony.gutierrez@amd.com deschedule(&tickEvent); 10611308Santhony.gutierrez@amd.com 10711308Santhony.gutierrez@amd.com UNSERIALIZE_SCALAR(event_tick); 10811308Santhony.gutierrez@amd.com 10911308Santhony.gutierrez@amd.com if (event_tick) 11011308Santhony.gutierrez@amd.com schedule(&tickEvent, event_tick); 11111308Santhony.gutierrez@amd.com} 11211308Santhony.gutierrez@amd.com 11311308Santhony.gutierrez@amd.comAddrRangeList 11411308Santhony.gutierrez@amd.comGpuDispatcher::getAddrRanges() const 11511308Santhony.gutierrez@amd.com{ 11611308Santhony.gutierrez@amd.com AddrRangeList ranges; 11711308Santhony.gutierrez@amd.com 11811308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "dispatcher registering addr range at %#x size %#x\n", 11911308Santhony.gutierrez@amd.com pioAddr, pioSize); 12011308Santhony.gutierrez@amd.com 12111308Santhony.gutierrez@amd.com ranges.push_back(RangeSize(pioAddr, pioSize)); 12211308Santhony.gutierrez@amd.com 12311308Santhony.gutierrez@amd.com return ranges; 12411308Santhony.gutierrez@amd.com} 12511308Santhony.gutierrez@amd.com 12611308Santhony.gutierrez@amd.comTick 12711308Santhony.gutierrez@amd.comGpuDispatcher::read(PacketPtr pkt) 12811308Santhony.gutierrez@amd.com{ 12911308Santhony.gutierrez@amd.com assert(pkt->getAddr() >= pioAddr); 13011308Santhony.gutierrez@amd.com assert(pkt->getAddr() < pioAddr + pioSize); 13111308Santhony.gutierrez@amd.com 13211308Santhony.gutierrez@amd.com int offset = pkt->getAddr() - pioAddr; 13311308Santhony.gutierrez@amd.com pkt->allocate(); 13411308Santhony.gutierrez@amd.com 13511308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, " read register %#x size=%d\n", offset, pkt->getSize()); 13611308Santhony.gutierrez@amd.com 13711308Santhony.gutierrez@amd.com if (offset < 8) { 13811308Santhony.gutierrez@amd.com assert(!offset); 13911308Santhony.gutierrez@amd.com assert(pkt->getSize() == 8); 14011308Santhony.gutierrez@amd.com 14111308Santhony.gutierrez@amd.com uint64_t retval = dispatchActive; 14213345Sgabeblack@google.com pkt->setLE(retval); 14311308Santhony.gutierrez@amd.com } else { 14411308Santhony.gutierrez@amd.com offset -= 8; 14511308Santhony.gutierrez@amd.com assert(offset + pkt->getSize() < sizeof(HsaQueueEntry)); 14611308Santhony.gutierrez@amd.com char *curTaskPtr = (char*)&curTask; 14711308Santhony.gutierrez@amd.com 14811308Santhony.gutierrez@amd.com memcpy(pkt->getPtr<const void*>(), curTaskPtr + offset, pkt->getSize()); 14911308Santhony.gutierrez@amd.com } 15011308Santhony.gutierrez@amd.com 15111308Santhony.gutierrez@amd.com pkt->makeAtomicResponse(); 15211308Santhony.gutierrez@amd.com 15311308Santhony.gutierrez@amd.com return pioDelay; 15411308Santhony.gutierrez@amd.com} 15511308Santhony.gutierrez@amd.com 15611308Santhony.gutierrez@amd.comTick 15711308Santhony.gutierrez@amd.comGpuDispatcher::write(PacketPtr pkt) 15811308Santhony.gutierrez@amd.com{ 15911308Santhony.gutierrez@amd.com assert(pkt->getAddr() >= pioAddr); 16011308Santhony.gutierrez@amd.com assert(pkt->getAddr() < pioAddr + pioSize); 16111308Santhony.gutierrez@amd.com 16211308Santhony.gutierrez@amd.com int offset = pkt->getAddr() - pioAddr; 16311308Santhony.gutierrez@amd.com 16411308Santhony.gutierrez@amd.com#if TRACING_ON 16511308Santhony.gutierrez@amd.com uint64_t data_val = 0; 16611308Santhony.gutierrez@amd.com 16711308Santhony.gutierrez@amd.com switch (pkt->getSize()) { 16811308Santhony.gutierrez@amd.com case 1: 16913345Sgabeblack@google.com data_val = pkt->getLE<uint8_t>(); 17011308Santhony.gutierrez@amd.com break; 17111308Santhony.gutierrez@amd.com case 2: 17213345Sgabeblack@google.com data_val = pkt->getLE<uint16_t>(); 17311308Santhony.gutierrez@amd.com break; 17411308Santhony.gutierrez@amd.com case 4: 17513345Sgabeblack@google.com data_val = pkt->getLE<uint32_t>(); 17611308Santhony.gutierrez@amd.com break; 17711308Santhony.gutierrez@amd.com case 8: 17813345Sgabeblack@google.com data_val = pkt->getLE<uint64_t>(); 17911308Santhony.gutierrez@amd.com break; 18011308Santhony.gutierrez@amd.com default: 18111308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "bad size %d\n", pkt->getSize()); 18211308Santhony.gutierrez@amd.com } 18311308Santhony.gutierrez@amd.com 18411308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "write register %#x value %#x size=%d\n", offset, data_val, 18511308Santhony.gutierrez@amd.com pkt->getSize()); 18611308Santhony.gutierrez@amd.com#endif 18711308Santhony.gutierrez@amd.com if (!offset) { 18811308Santhony.gutierrez@amd.com static int nextId = 0; 18911308Santhony.gutierrez@amd.com 19011308Santhony.gutierrez@amd.com // The depends field of the qstruct, which was previously unused, is 19111308Santhony.gutierrez@amd.com // used to communicate with simulated application. 19211308Santhony.gutierrez@amd.com if (curTask.depends) { 19311308Santhony.gutierrez@amd.com HostState hs; 19411308Santhony.gutierrez@amd.com shader->ReadMem((uint64_t)(curTask.depends), &hs, 19511308Santhony.gutierrez@amd.com sizeof(HostState), 0); 19611308Santhony.gutierrez@amd.com 19711308Santhony.gutierrez@amd.com // update event start time (in nano-seconds) 19811308Santhony.gutierrez@amd.com uint64_t start = curTick() / 1000; 19911308Santhony.gutierrez@amd.com 20011308Santhony.gutierrez@amd.com shader->WriteMem((uint64_t)(&((_cl_event*)hs.event)->start), 20111308Santhony.gutierrez@amd.com &start, sizeof(uint64_t), 0); 20211308Santhony.gutierrez@amd.com } 20311308Santhony.gutierrez@amd.com 20411308Santhony.gutierrez@amd.com // launch kernel 20511308Santhony.gutierrez@amd.com ++num_kernelLaunched; 20611308Santhony.gutierrez@amd.com 20711308Santhony.gutierrez@amd.com NDRange *ndr = &(ndRangeMap[nextId]); 20811308Santhony.gutierrez@amd.com // copy dispatch info 20911308Santhony.gutierrez@amd.com ndr->q = curTask; 21011308Santhony.gutierrez@amd.com 21111308Santhony.gutierrez@amd.com // update the numDispTask polled by the runtime 21211308Santhony.gutierrez@amd.com accessUserVar(cpu, (uint64_t)(curTask.numDispLeft), 0, 1); 21311308Santhony.gutierrez@amd.com 21411308Santhony.gutierrez@amd.com ndr->numWgTotal = 1; 21511308Santhony.gutierrez@amd.com 21611308Santhony.gutierrez@amd.com for (int i = 0; i < 3; ++i) { 21711308Santhony.gutierrez@amd.com ndr->wgId[i] = 0; 21811308Santhony.gutierrez@amd.com ndr->numWg[i] = divCeil(curTask.gdSize[i], curTask.wgSize[i]); 21911308Santhony.gutierrez@amd.com ndr->numWgTotal *= ndr->numWg[i]; 22011308Santhony.gutierrez@amd.com } 22111308Santhony.gutierrez@amd.com 22211308Santhony.gutierrez@amd.com ndr->numWgCompleted = 0; 22311308Santhony.gutierrez@amd.com ndr->globalWgId = 0; 22411308Santhony.gutierrez@amd.com ndr->wg_disp_rem = true; 22511308Santhony.gutierrez@amd.com ndr->execDone = false; 22611308Santhony.gutierrez@amd.com ndr->addrToNotify = (volatile bool*)curTask.addrToNotify; 22711308Santhony.gutierrez@amd.com ndr->numDispLeft = (volatile uint32_t*)curTask.numDispLeft; 22811308Santhony.gutierrez@amd.com ndr->dispatchId = nextId; 22911435Smitch.hayenga@arm.com ndr->curCid = pkt->req->contextId(); 23011308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "launching kernel %d\n",nextId); 23111308Santhony.gutierrez@amd.com execIds.push(nextId); 23211308Santhony.gutierrez@amd.com ++nextId; 23311308Santhony.gutierrez@amd.com 23411308Santhony.gutierrez@amd.com dispatchActive = true; 23511308Santhony.gutierrez@amd.com 23611308Santhony.gutierrez@amd.com if (!tickEvent.scheduled()) { 23711308Santhony.gutierrez@amd.com schedule(&tickEvent, curTick() + shader->ticks(1)); 23811308Santhony.gutierrez@amd.com } 23911308Santhony.gutierrez@amd.com } else { 24011308Santhony.gutierrez@amd.com // populate current task struct 24111308Santhony.gutierrez@amd.com // first 64 bits are launch reg 24211308Santhony.gutierrez@amd.com offset -= 8; 24311308Santhony.gutierrez@amd.com assert(offset < sizeof(HsaQueueEntry)); 24411308Santhony.gutierrez@amd.com char *curTaskPtr = (char*)&curTask; 24511308Santhony.gutierrez@amd.com memcpy(curTaskPtr + offset, pkt->getPtr<const void*>(), pkt->getSize()); 24611308Santhony.gutierrez@amd.com } 24711308Santhony.gutierrez@amd.com 24811308Santhony.gutierrez@amd.com pkt->makeAtomicResponse(); 24911308Santhony.gutierrez@amd.com 25011308Santhony.gutierrez@amd.com return pioDelay; 25111308Santhony.gutierrez@amd.com} 25211308Santhony.gutierrez@amd.com 25311308Santhony.gutierrez@amd.com 25413784Sgabeblack@google.comPort & 25513784Sgabeblack@google.comGpuDispatcher::getPort(const std::string &if_name, PortID idx) 25611308Santhony.gutierrez@amd.com{ 25711308Santhony.gutierrez@amd.com if (if_name == "translation_port") { 25811308Santhony.gutierrez@amd.com return *tlbPort; 25911308Santhony.gutierrez@amd.com } 26011308Santhony.gutierrez@amd.com 26113784Sgabeblack@google.com return DmaDevice::getPort(if_name, idx); 26211308Santhony.gutierrez@amd.com} 26311308Santhony.gutierrez@amd.com 26411308Santhony.gutierrez@amd.comvoid 26511308Santhony.gutierrez@amd.comGpuDispatcher::exec() 26611308Santhony.gutierrez@amd.com{ 26711308Santhony.gutierrez@amd.com int fail_count = 0; 26811308Santhony.gutierrez@amd.com 26911308Santhony.gutierrez@amd.com // There are potentially multiple outstanding kernel launches. 27011308Santhony.gutierrez@amd.com // It is possible that the workgroups in a different kernel 27111308Santhony.gutierrez@amd.com // can fit on the GPU even if another kernel's workgroups cannot 27211308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "Launching %d Kernels\n", execIds.size()); 27311308Santhony.gutierrez@amd.com 27411308Santhony.gutierrez@amd.com while (execIds.size() > fail_count) { 27511308Santhony.gutierrez@amd.com int execId = execIds.front(); 27611308Santhony.gutierrez@amd.com 27711308Santhony.gutierrez@amd.com while (ndRangeMap[execId].wg_disp_rem) { 27811308Santhony.gutierrez@amd.com //update the thread context 27911435Smitch.hayenga@arm.com shader->updateContext(ndRangeMap[execId].curCid); 28011308Santhony.gutierrez@amd.com 28111308Santhony.gutierrez@amd.com // attempt to dispatch_workgroup 28211308Santhony.gutierrez@amd.com if (!shader->dispatch_workgroups(&ndRangeMap[execId])) { 28311308Santhony.gutierrez@amd.com // if we failed try the next kernel, 28411308Santhony.gutierrez@amd.com // it may have smaller workgroups. 28511308Santhony.gutierrez@amd.com // put it on the queue to rety latter 28611308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "kernel %d failed to launch\n", execId); 28711308Santhony.gutierrez@amd.com execIds.push(execId); 28811308Santhony.gutierrez@amd.com ++fail_count; 28911308Santhony.gutierrez@amd.com break; 29011308Santhony.gutierrez@amd.com } 29111308Santhony.gutierrez@amd.com } 29211308Santhony.gutierrez@amd.com // let's try the next kernel_id 29311308Santhony.gutierrez@amd.com execIds.pop(); 29411308Santhony.gutierrez@amd.com } 29511308Santhony.gutierrez@amd.com 29611308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "Returning %d Kernels\n", doneIds.size()); 29711308Santhony.gutierrez@amd.com 29811308Santhony.gutierrez@amd.com if (doneIds.size() && cpu) { 29911308Santhony.gutierrez@amd.com shader->hostWakeUp(cpu); 30011308Santhony.gutierrez@amd.com } 30111308Santhony.gutierrez@amd.com 30211308Santhony.gutierrez@amd.com while (doneIds.size()) { 30311308Santhony.gutierrez@amd.com // wakeup the CPU if any Kernels completed this cycle 30411308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "WorkGroup %d completed\n", doneIds.front()); 30511308Santhony.gutierrez@amd.com doneIds.pop(); 30611308Santhony.gutierrez@amd.com } 30711308Santhony.gutierrez@amd.com} 30811308Santhony.gutierrez@amd.com 30911308Santhony.gutierrez@amd.comvoid 31011308Santhony.gutierrez@amd.comGpuDispatcher::notifyWgCompl(Wavefront *w) 31111308Santhony.gutierrez@amd.com{ 31211639Salexandru.dutu@amd.com int kern_id = w->kernId; 31311308Santhony.gutierrez@amd.com DPRINTF(GPUDisp, "notify WgCompl %d\n",kern_id); 31411308Santhony.gutierrez@amd.com assert(ndRangeMap[kern_id].dispatchId == kern_id); 31511308Santhony.gutierrez@amd.com ndRangeMap[kern_id].numWgCompleted++; 31611308Santhony.gutierrez@amd.com 31711308Santhony.gutierrez@amd.com if (ndRangeMap[kern_id].numWgCompleted == ndRangeMap[kern_id].numWgTotal) { 31811308Santhony.gutierrez@amd.com ndRangeMap[kern_id].execDone = true; 31911308Santhony.gutierrez@amd.com doneIds.push(kern_id); 32011308Santhony.gutierrez@amd.com 32111308Santhony.gutierrez@amd.com if (ndRangeMap[kern_id].addrToNotify) { 32211308Santhony.gutierrez@amd.com accessUserVar(cpu, (uint64_t)(ndRangeMap[kern_id].addrToNotify), 1, 32311308Santhony.gutierrez@amd.com 0); 32411308Santhony.gutierrez@amd.com } 32511308Santhony.gutierrez@amd.com 32611308Santhony.gutierrez@amd.com accessUserVar(cpu, (uint64_t)(ndRangeMap[kern_id].numDispLeft), 0, -1); 32711308Santhony.gutierrez@amd.com 32811308Santhony.gutierrez@amd.com // update event end time (in nano-seconds) 32911308Santhony.gutierrez@amd.com if (ndRangeMap[kern_id].q.depends) { 33011308Santhony.gutierrez@amd.com HostState *host_state = (HostState*)ndRangeMap[kern_id].q.depends; 33111308Santhony.gutierrez@amd.com uint64_t event; 33211308Santhony.gutierrez@amd.com shader->ReadMem((uint64_t)(&host_state->event), &event, 33311308Santhony.gutierrez@amd.com sizeof(uint64_t), 0); 33411308Santhony.gutierrez@amd.com 33511308Santhony.gutierrez@amd.com uint64_t end = curTick() / 1000; 33611308Santhony.gutierrez@amd.com 33711308Santhony.gutierrez@amd.com shader->WriteMem((uint64_t)(&((_cl_event*)event)->end), &end, 33811308Santhony.gutierrez@amd.com sizeof(uint64_t), 0); 33911308Santhony.gutierrez@amd.com } 34011308Santhony.gutierrez@amd.com } 34111308Santhony.gutierrez@amd.com 34211308Santhony.gutierrez@amd.com if (!tickEvent.scheduled()) { 34311308Santhony.gutierrez@amd.com schedule(&tickEvent, curTick() + shader->ticks(1)); 34411308Santhony.gutierrez@amd.com } 34511308Santhony.gutierrez@amd.com} 34611308Santhony.gutierrez@amd.com 34711308Santhony.gutierrez@amd.comvoid 34811308Santhony.gutierrez@amd.comGpuDispatcher::scheduleDispatch() 34911308Santhony.gutierrez@amd.com{ 35011308Santhony.gutierrez@amd.com if (!tickEvent.scheduled()) 35111308Santhony.gutierrez@amd.com schedule(&tickEvent, curTick() + shader->ticks(1)); 35211308Santhony.gutierrez@amd.com} 35311308Santhony.gutierrez@amd.com 35411308Santhony.gutierrez@amd.comvoid 35511308Santhony.gutierrez@amd.comGpuDispatcher::accessUserVar(BaseCPU *cpu, uint64_t addr, int val, int off) 35611308Santhony.gutierrez@amd.com{ 35711308Santhony.gutierrez@amd.com if (cpu) { 35811308Santhony.gutierrez@amd.com if (off) { 35911308Santhony.gutierrez@amd.com shader->AccessMem(addr, &val, sizeof(int), 0, MemCmd::ReadReq, 36011308Santhony.gutierrez@amd.com true); 36111308Santhony.gutierrez@amd.com val += off; 36211308Santhony.gutierrez@amd.com } 36311308Santhony.gutierrez@amd.com 36411308Santhony.gutierrez@amd.com shader->AccessMem(addr, &val, sizeof(int), 0, MemCmd::WriteReq, true); 36511308Santhony.gutierrez@amd.com } else { 36611308Santhony.gutierrez@amd.com panic("Cannot find host"); 36711308Santhony.gutierrez@amd.com } 36811308Santhony.gutierrez@amd.com} 36911308Santhony.gutierrez@amd.com 37011308Santhony.gutierrez@amd.com// helper functions for driver to retrieve GPU attributes 37111308Santhony.gutierrez@amd.comint 37211308Santhony.gutierrez@amd.comGpuDispatcher::getNumCUs() 37311308Santhony.gutierrez@amd.com{ 37411308Santhony.gutierrez@amd.com return shader->cuList.size(); 37511308Santhony.gutierrez@amd.com} 37611308Santhony.gutierrez@amd.com 37711534Sjohn.kalamatianos@amd.comint 37811534Sjohn.kalamatianos@amd.comGpuDispatcher::wfSize() const 37911534Sjohn.kalamatianos@amd.com{ 38011534Sjohn.kalamatianos@amd.com return shader->cuList[0]->wfSize(); 38111534Sjohn.kalamatianos@amd.com} 38211534Sjohn.kalamatianos@amd.com 38311308Santhony.gutierrez@amd.comvoid 38411308Santhony.gutierrez@amd.comGpuDispatcher::setFuncargsSize(int funcargs_size) 38511308Santhony.gutierrez@amd.com{ 38611308Santhony.gutierrez@amd.com shader->funcargs_size = funcargs_size; 38711308Santhony.gutierrez@amd.com} 38811640Salexandru.dutu@amd.com 38911640Salexandru.dutu@amd.comuint32_t 39011646Santhony.gutierrez@amd.comGpuDispatcher::getStaticContextSize() const 39111640Salexandru.dutu@amd.com{ 39211640Salexandru.dutu@amd.com return shader->cuList[0]->wfList[0][0]->getStaticContextSize(); 39311640Salexandru.dutu@amd.com} 394