cl_driver.cc revision 11856
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2012-2015 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 * 1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors 1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software 1911308Santhony.gutierrez@amd.com * 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 * 3311308Santhony.gutierrez@amd.com * Author: Anthony Gutierrez 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#include "gpu-compute/cl_driver.hh" 3711308Santhony.gutierrez@amd.com 3811856Sbrandon.potter@amd.com#include <memory> 3911856Sbrandon.potter@amd.com 4011308Santhony.gutierrez@amd.com#include "base/intmath.hh" 4111308Santhony.gutierrez@amd.com#include "cpu/thread_context.hh" 4211308Santhony.gutierrez@amd.com#include "gpu-compute/dispatcher.hh" 4311308Santhony.gutierrez@amd.com#include "gpu-compute/hsa_code.hh" 4411308Santhony.gutierrez@amd.com#include "gpu-compute/hsa_kernel_info.hh" 4511308Santhony.gutierrez@amd.com#include "gpu-compute/hsa_object.hh" 4611308Santhony.gutierrez@amd.com#include "params/ClDriver.hh" 4711308Santhony.gutierrez@amd.com#include "sim/process.hh" 4811308Santhony.gutierrez@amd.com#include "sim/syscall_emul_buf.hh" 4911308Santhony.gutierrez@amd.com 5011308Santhony.gutierrez@amd.comClDriver::ClDriver(ClDriverParams *p) 5111308Santhony.gutierrez@amd.com : EmulatedDriver(p), hsaCode(0) 5211308Santhony.gutierrez@amd.com{ 5311308Santhony.gutierrez@amd.com for (const auto &codeFile : p->codefile) 5411308Santhony.gutierrez@amd.com codeFiles.push_back(&codeFile); 5511308Santhony.gutierrez@amd.com 5611308Santhony.gutierrez@amd.com maxFuncArgsSize = 0; 5711308Santhony.gutierrez@amd.com 5811308Santhony.gutierrez@amd.com for (int i = 0; i < codeFiles.size(); ++i) { 5911308Santhony.gutierrez@amd.com HsaObject *obj = HsaObject::createHsaObject(*codeFiles[i]); 6011308Santhony.gutierrez@amd.com 6111308Santhony.gutierrez@amd.com for (int k = 0; k < obj->numKernels(); ++k) { 6211308Santhony.gutierrez@amd.com assert(obj->getKernel(k)); 6311308Santhony.gutierrez@amd.com kernels.push_back(obj->getKernel(k)); 6411308Santhony.gutierrez@amd.com kernels.back()->setReadonlyData((uint8_t*)obj->readonlyData); 6511308Santhony.gutierrez@amd.com int kern_funcargs_size = kernels.back()->funcarg_size; 6611308Santhony.gutierrez@amd.com maxFuncArgsSize = maxFuncArgsSize < kern_funcargs_size ? 6711308Santhony.gutierrez@amd.com kern_funcargs_size : maxFuncArgsSize; 6811308Santhony.gutierrez@amd.com } 6911308Santhony.gutierrez@amd.com } 7011308Santhony.gutierrez@amd.com 7111308Santhony.gutierrez@amd.com int name_offs = 0; 7211308Santhony.gutierrez@amd.com int code_offs = 0; 7311308Santhony.gutierrez@amd.com 7411308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 7511308Santhony.gutierrez@amd.com kernelInfo.push_back(HsaKernelInfo()); 7611308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 7711308Santhony.gutierrez@amd.com 7811308Santhony.gutierrez@amd.com k->generateHsaKernelInfo(&kernelInfo[i]); 7911308Santhony.gutierrez@amd.com 8011308Santhony.gutierrez@amd.com kernelInfo[i].name_offs = name_offs; 8111308Santhony.gutierrez@amd.com kernelInfo[i].code_offs = code_offs; 8211308Santhony.gutierrez@amd.com 8311308Santhony.gutierrez@amd.com name_offs += k->name().size() + 1; 8411697Santhony.gutierrez@amd.com code_offs += k->numInsts() * sizeof(TheGpuISA::RawMachInst); 8511308Santhony.gutierrez@amd.com } 8611308Santhony.gutierrez@amd.com} 8711308Santhony.gutierrez@amd.com 8811308Santhony.gutierrez@amd.comvoid 8911308Santhony.gutierrez@amd.comClDriver::handshake(GpuDispatcher *_dispatcher) 9011308Santhony.gutierrez@amd.com{ 9111308Santhony.gutierrez@amd.com dispatcher = _dispatcher; 9211308Santhony.gutierrez@amd.com dispatcher->setFuncargsSize(maxFuncArgsSize); 9311308Santhony.gutierrez@amd.com} 9411308Santhony.gutierrez@amd.com 9511308Santhony.gutierrez@amd.comint 9611851Sbrandon.potter@amd.comClDriver::open(Process *p, ThreadContext *tc, int mode, int flags) 9711308Santhony.gutierrez@amd.com{ 9811856Sbrandon.potter@amd.com std::shared_ptr<DeviceFDEntry> fdp; 9911856Sbrandon.potter@amd.com fdp = std::make_shared<DeviceFDEntry>(this, filename); 10011856Sbrandon.potter@amd.com int tgt_fd = p->fds->allocFD(fdp); 10111856Sbrandon.potter@amd.com return tgt_fd; 10211308Santhony.gutierrez@amd.com} 10311308Santhony.gutierrez@amd.com 10411308Santhony.gutierrez@amd.comint 10511851Sbrandon.potter@amd.comClDriver::ioctl(Process *process, ThreadContext *tc, unsigned req) 10611308Santhony.gutierrez@amd.com{ 10711308Santhony.gutierrez@amd.com int index = 2; 10811308Santhony.gutierrez@amd.com Addr buf_addr = process->getSyscallArg(tc, index); 10911308Santhony.gutierrez@amd.com 11011308Santhony.gutierrez@amd.com switch (req) { 11111308Santhony.gutierrez@amd.com case HSA_GET_SIZES: 11211308Santhony.gutierrez@amd.com { 11311308Santhony.gutierrez@amd.com TypedBufferArg<HsaDriverSizes> sizes(buf_addr); 11411308Santhony.gutierrez@amd.com sizes->num_kernels = kernels.size(); 11511308Santhony.gutierrez@amd.com sizes->string_table_size = 0; 11611308Santhony.gutierrez@amd.com sizes->code_size = 0; 11711308Santhony.gutierrez@amd.com sizes->readonly_size = 0; 11811308Santhony.gutierrez@amd.com 11911308Santhony.gutierrez@amd.com if (kernels.size() > 0) { 12011308Santhony.gutierrez@amd.com // all kernels will share the same read-only memory 12111308Santhony.gutierrez@amd.com sizes->readonly_size = 12211308Santhony.gutierrez@amd.com kernels[0]->getSize(HsaCode::MemorySegment::READONLY); 12311308Santhony.gutierrez@amd.com // check our assumption 12411308Santhony.gutierrez@amd.com for (int i = 1; i<kernels.size(); ++i) { 12511308Santhony.gutierrez@amd.com assert(sizes->readonly_size == 12611308Santhony.gutierrez@amd.com kernels[i]->getSize(HsaCode::MemorySegment::READONLY)); 12711308Santhony.gutierrez@amd.com } 12811308Santhony.gutierrez@amd.com } 12911308Santhony.gutierrez@amd.com 13011308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 13111308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 13211308Santhony.gutierrez@amd.com // add one for terminating '\0' 13311308Santhony.gutierrez@amd.com sizes->string_table_size += k->name().size() + 1; 13411697Santhony.gutierrez@amd.com sizes->code_size += 13511697Santhony.gutierrez@amd.com k->numInsts() * sizeof(TheGpuISA::RawMachInst); 13611308Santhony.gutierrez@amd.com } 13711308Santhony.gutierrez@amd.com 13811308Santhony.gutierrez@amd.com sizes.copyOut(tc->getMemProxy()); 13911308Santhony.gutierrez@amd.com } 14011308Santhony.gutierrez@amd.com break; 14111308Santhony.gutierrez@amd.com 14211308Santhony.gutierrez@amd.com case HSA_GET_KINFO: 14311308Santhony.gutierrez@amd.com { 14411308Santhony.gutierrez@amd.com TypedBufferArg<HsaKernelInfo> 14511308Santhony.gutierrez@amd.com kinfo(buf_addr, sizeof(HsaKernelInfo) * kernels.size()); 14611308Santhony.gutierrez@amd.com 14711308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 14811308Santhony.gutierrez@amd.com HsaKernelInfo *ki = &kinfo[i]; 14911308Santhony.gutierrez@amd.com ki->name_offs = kernelInfo[i].name_offs; 15011308Santhony.gutierrez@amd.com ki->code_offs = kernelInfo[i].code_offs; 15111308Santhony.gutierrez@amd.com ki->sRegCount = kernelInfo[i].sRegCount; 15211308Santhony.gutierrez@amd.com ki->dRegCount = kernelInfo[i].dRegCount; 15311308Santhony.gutierrez@amd.com ki->cRegCount = kernelInfo[i].cRegCount; 15411308Santhony.gutierrez@amd.com ki->static_lds_size = kernelInfo[i].static_lds_size; 15511308Santhony.gutierrez@amd.com ki->private_mem_size = kernelInfo[i].private_mem_size; 15611308Santhony.gutierrez@amd.com ki->spill_mem_size = kernelInfo[i].spill_mem_size; 15711308Santhony.gutierrez@amd.com } 15811308Santhony.gutierrez@amd.com 15911308Santhony.gutierrez@amd.com kinfo.copyOut(tc->getMemProxy()); 16011308Santhony.gutierrez@amd.com } 16111308Santhony.gutierrez@amd.com break; 16211308Santhony.gutierrez@amd.com 16311308Santhony.gutierrez@amd.com case HSA_GET_STRINGS: 16411308Santhony.gutierrez@amd.com { 16511308Santhony.gutierrez@amd.com int string_table_size = 0; 16611308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 16711308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 16811308Santhony.gutierrez@amd.com string_table_size += k->name().size() + 1; 16911308Santhony.gutierrez@amd.com } 17011308Santhony.gutierrez@amd.com 17111308Santhony.gutierrez@amd.com BufferArg buf(buf_addr, string_table_size); 17211308Santhony.gutierrez@amd.com char *bufp = (char*)buf.bufferPtr(); 17311308Santhony.gutierrez@amd.com 17411308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 17511308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 17611308Santhony.gutierrez@amd.com const char *n = k->name().c_str(); 17711308Santhony.gutierrez@amd.com 17811308Santhony.gutierrez@amd.com // idiomatic string copy 17911308Santhony.gutierrez@amd.com while ((*bufp++ = *n++)); 18011308Santhony.gutierrez@amd.com } 18111308Santhony.gutierrez@amd.com 18211308Santhony.gutierrez@amd.com assert(bufp - (char *)buf.bufferPtr() == string_table_size); 18311308Santhony.gutierrez@amd.com 18411308Santhony.gutierrez@amd.com buf.copyOut(tc->getMemProxy()); 18511308Santhony.gutierrez@amd.com } 18611308Santhony.gutierrez@amd.com break; 18711308Santhony.gutierrez@amd.com 18811308Santhony.gutierrez@amd.com case HSA_GET_READONLY_DATA: 18911308Santhony.gutierrez@amd.com { 19011308Santhony.gutierrez@amd.com // we can pick any kernel --- they share the same 19111308Santhony.gutierrez@amd.com // readonly segment (this assumption is checked in GET_SIZES) 19211308Santhony.gutierrez@amd.com uint64_t size = 19311308Santhony.gutierrez@amd.com kernels.back()->getSize(HsaCode::MemorySegment::READONLY); 19411308Santhony.gutierrez@amd.com BufferArg data(buf_addr, size); 19511308Santhony.gutierrez@amd.com char *datap = (char *)data.bufferPtr(); 19611308Santhony.gutierrez@amd.com memcpy(datap, 19711308Santhony.gutierrez@amd.com kernels.back()->readonly_data, 19811308Santhony.gutierrez@amd.com size); 19911308Santhony.gutierrez@amd.com data.copyOut(tc->getMemProxy()); 20011308Santhony.gutierrez@amd.com } 20111308Santhony.gutierrez@amd.com break; 20211308Santhony.gutierrez@amd.com 20311308Santhony.gutierrez@amd.com case HSA_GET_CODE: 20411308Santhony.gutierrez@amd.com { 20511308Santhony.gutierrez@amd.com // set hsaCode pointer 20611308Santhony.gutierrez@amd.com hsaCode = buf_addr; 20711308Santhony.gutierrez@amd.com int code_size = 0; 20811308Santhony.gutierrez@amd.com 20911308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 21011308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 21111308Santhony.gutierrez@amd.com code_size += k->numInsts() * sizeof(TheGpuISA::RawMachInst); 21211308Santhony.gutierrez@amd.com } 21311308Santhony.gutierrez@amd.com 21411308Santhony.gutierrez@amd.com TypedBufferArg<TheGpuISA::RawMachInst> buf(buf_addr, code_size); 21511308Santhony.gutierrez@amd.com TheGpuISA::RawMachInst *bufp = buf; 21611308Santhony.gutierrez@amd.com 21711308Santhony.gutierrez@amd.com int buf_idx = 0; 21811308Santhony.gutierrez@amd.com 21911308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 22011308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 22111308Santhony.gutierrez@amd.com 22211308Santhony.gutierrez@amd.com for (int j = 0; j < k->numInsts(); ++j) { 22311308Santhony.gutierrez@amd.com bufp[buf_idx] = k->insts()->at(j); 22411308Santhony.gutierrez@amd.com ++buf_idx; 22511308Santhony.gutierrez@amd.com } 22611308Santhony.gutierrez@amd.com } 22711308Santhony.gutierrez@amd.com 22811308Santhony.gutierrez@amd.com buf.copyOut(tc->getMemProxy()); 22911308Santhony.gutierrez@amd.com } 23011308Santhony.gutierrez@amd.com break; 23111308Santhony.gutierrez@amd.com 23211308Santhony.gutierrez@amd.com case HSA_GET_CU_CNT: 23311308Santhony.gutierrez@amd.com { 23411308Santhony.gutierrez@amd.com BufferArg buf(buf_addr, sizeof(uint32_t)); 23511308Santhony.gutierrez@amd.com *((uint32_t*)buf.bufferPtr()) = dispatcher->getNumCUs(); 23611308Santhony.gutierrez@amd.com buf.copyOut(tc->getMemProxy()); 23711308Santhony.gutierrez@amd.com } 23811308Santhony.gutierrez@amd.com break; 23911308Santhony.gutierrez@amd.com 24011308Santhony.gutierrez@amd.com case HSA_GET_VSZ: 24111308Santhony.gutierrez@amd.com { 24211308Santhony.gutierrez@amd.com BufferArg buf(buf_addr, sizeof(uint32_t)); 24311534Sjohn.kalamatianos@amd.com *((uint32_t*)buf.bufferPtr()) = dispatcher->wfSize(); 24411308Santhony.gutierrez@amd.com buf.copyOut(tc->getMemProxy()); 24511308Santhony.gutierrez@amd.com } 24611308Santhony.gutierrez@amd.com break; 24711640Salexandru.dutu@amd.com case HSA_GET_HW_STATIC_CONTEXT_SIZE: 24811640Salexandru.dutu@amd.com { 24911640Salexandru.dutu@amd.com BufferArg buf(buf_addr, sizeof(uint32_t)); 25011640Salexandru.dutu@amd.com *((uint32_t*)buf.bufferPtr()) = dispatcher->getStaticContextSize(); 25111640Salexandru.dutu@amd.com buf.copyOut(tc->getMemProxy()); 25211640Salexandru.dutu@amd.com } 25311640Salexandru.dutu@amd.com break; 25411308Santhony.gutierrez@amd.com 25511308Santhony.gutierrez@amd.com default: 25611308Santhony.gutierrez@amd.com fatal("ClDriver: bad ioctl %d\n", req); 25711308Santhony.gutierrez@amd.com } 25811308Santhony.gutierrez@amd.com 25911308Santhony.gutierrez@amd.com return 0; 26011308Santhony.gutierrez@amd.com} 26111308Santhony.gutierrez@amd.com 26211308Santhony.gutierrez@amd.comconst char* 26311308Santhony.gutierrez@amd.comClDriver::codeOffToKernelName(uint64_t code_ptr) 26411308Santhony.gutierrez@amd.com{ 26511308Santhony.gutierrez@amd.com assert(hsaCode); 26611308Santhony.gutierrez@amd.com uint32_t code_offs = code_ptr - hsaCode; 26711308Santhony.gutierrez@amd.com 26811308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 26911308Santhony.gutierrez@amd.com if (code_offs == kernelInfo[i].code_offs) { 27011308Santhony.gutierrez@amd.com return kernels[i]->name().c_str(); 27111308Santhony.gutierrez@amd.com } 27211308Santhony.gutierrez@amd.com } 27311308Santhony.gutierrez@amd.com 27411308Santhony.gutierrez@amd.com return nullptr; 27511308Santhony.gutierrez@amd.com} 27611308Santhony.gutierrez@amd.com 27711308Santhony.gutierrez@amd.comClDriver* 27811308Santhony.gutierrez@amd.comClDriverParams::create() 27911308Santhony.gutierrez@amd.com{ 28011308Santhony.gutierrez@amd.com return new ClDriver(this); 28111308Santhony.gutierrez@amd.com} 282