cl_driver.cc revision 11308
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 3811308Santhony.gutierrez@amd.com#include "base/intmath.hh" 3911308Santhony.gutierrez@amd.com#include "cpu/thread_context.hh" 4011308Santhony.gutierrez@amd.com#include "gpu-compute/dispatcher.hh" 4111308Santhony.gutierrez@amd.com#include "gpu-compute/hsa_code.hh" 4211308Santhony.gutierrez@amd.com#include "gpu-compute/hsa_kernel_info.hh" 4311308Santhony.gutierrez@amd.com#include "gpu-compute/hsa_object.hh" 4411308Santhony.gutierrez@amd.com#include "params/ClDriver.hh" 4511308Santhony.gutierrez@amd.com#include "sim/process.hh" 4611308Santhony.gutierrez@amd.com#include "sim/syscall_emul_buf.hh" 4711308Santhony.gutierrez@amd.com 4811308Santhony.gutierrez@amd.comClDriver::ClDriver(ClDriverParams *p) 4911308Santhony.gutierrez@amd.com : EmulatedDriver(p), hsaCode(0) 5011308Santhony.gutierrez@amd.com{ 5111308Santhony.gutierrez@amd.com for (const auto &codeFile : p->codefile) 5211308Santhony.gutierrez@amd.com codeFiles.push_back(&codeFile); 5311308Santhony.gutierrez@amd.com 5411308Santhony.gutierrez@amd.com maxFuncArgsSize = 0; 5511308Santhony.gutierrez@amd.com 5611308Santhony.gutierrez@amd.com for (int i = 0; i < codeFiles.size(); ++i) { 5711308Santhony.gutierrez@amd.com HsaObject *obj = HsaObject::createHsaObject(*codeFiles[i]); 5811308Santhony.gutierrez@amd.com 5911308Santhony.gutierrez@amd.com for (int k = 0; k < obj->numKernels(); ++k) { 6011308Santhony.gutierrez@amd.com assert(obj->getKernel(k)); 6111308Santhony.gutierrez@amd.com kernels.push_back(obj->getKernel(k)); 6211308Santhony.gutierrez@amd.com kernels.back()->setReadonlyData((uint8_t*)obj->readonlyData); 6311308Santhony.gutierrez@amd.com int kern_funcargs_size = kernels.back()->funcarg_size; 6411308Santhony.gutierrez@amd.com maxFuncArgsSize = maxFuncArgsSize < kern_funcargs_size ? 6511308Santhony.gutierrez@amd.com kern_funcargs_size : maxFuncArgsSize; 6611308Santhony.gutierrez@amd.com } 6711308Santhony.gutierrez@amd.com } 6811308Santhony.gutierrez@amd.com 6911308Santhony.gutierrez@amd.com int name_offs = 0; 7011308Santhony.gutierrez@amd.com int code_offs = 0; 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 7311308Santhony.gutierrez@amd.com kernelInfo.push_back(HsaKernelInfo()); 7411308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 7511308Santhony.gutierrez@amd.com 7611308Santhony.gutierrez@amd.com k->generateHsaKernelInfo(&kernelInfo[i]); 7711308Santhony.gutierrez@amd.com 7811308Santhony.gutierrez@amd.com kernelInfo[i].name_offs = name_offs; 7911308Santhony.gutierrez@amd.com kernelInfo[i].code_offs = code_offs; 8011308Santhony.gutierrez@amd.com 8111308Santhony.gutierrez@amd.com name_offs += k->name().size() + 1; 8211308Santhony.gutierrez@amd.com code_offs += k->numInsts() * sizeof(GPUStaticInst*); 8311308Santhony.gutierrez@amd.com } 8411308Santhony.gutierrez@amd.com} 8511308Santhony.gutierrez@amd.com 8611308Santhony.gutierrez@amd.comvoid 8711308Santhony.gutierrez@amd.comClDriver::handshake(GpuDispatcher *_dispatcher) 8811308Santhony.gutierrez@amd.com{ 8911308Santhony.gutierrez@amd.com dispatcher = _dispatcher; 9011308Santhony.gutierrez@amd.com dispatcher->setFuncargsSize(maxFuncArgsSize); 9111308Santhony.gutierrez@amd.com} 9211308Santhony.gutierrez@amd.com 9311308Santhony.gutierrez@amd.comint 9411308Santhony.gutierrez@amd.comClDriver::open(LiveProcess *p, ThreadContext *tc, int mode, int flags) 9511308Santhony.gutierrez@amd.com{ 9611308Santhony.gutierrez@amd.com int fd = p->allocFD(-1, filename, 0, 0, false); 9711308Santhony.gutierrez@amd.com FDEntry *fde = p->getFDEntry(fd); 9811308Santhony.gutierrez@amd.com fde->driver = this; 9911308Santhony.gutierrez@amd.com 10011308Santhony.gutierrez@amd.com return fd; 10111308Santhony.gutierrez@amd.com} 10211308Santhony.gutierrez@amd.com 10311308Santhony.gutierrez@amd.comint 10411308Santhony.gutierrez@amd.comClDriver::ioctl(LiveProcess *process, ThreadContext *tc, unsigned req) 10511308Santhony.gutierrez@amd.com{ 10611308Santhony.gutierrez@amd.com int index = 2; 10711308Santhony.gutierrez@amd.com Addr buf_addr = process->getSyscallArg(tc, index); 10811308Santhony.gutierrez@amd.com 10911308Santhony.gutierrez@amd.com switch (req) { 11011308Santhony.gutierrez@amd.com case HSA_GET_SIZES: 11111308Santhony.gutierrez@amd.com { 11211308Santhony.gutierrez@amd.com TypedBufferArg<HsaDriverSizes> sizes(buf_addr); 11311308Santhony.gutierrez@amd.com sizes->num_kernels = kernels.size(); 11411308Santhony.gutierrez@amd.com sizes->string_table_size = 0; 11511308Santhony.gutierrez@amd.com sizes->code_size = 0; 11611308Santhony.gutierrez@amd.com sizes->readonly_size = 0; 11711308Santhony.gutierrez@amd.com 11811308Santhony.gutierrez@amd.com if (kernels.size() > 0) { 11911308Santhony.gutierrez@amd.com // all kernels will share the same read-only memory 12011308Santhony.gutierrez@amd.com sizes->readonly_size = 12111308Santhony.gutierrez@amd.com kernels[0]->getSize(HsaCode::MemorySegment::READONLY); 12211308Santhony.gutierrez@amd.com // check our assumption 12311308Santhony.gutierrez@amd.com for (int i = 1; i<kernels.size(); ++i) { 12411308Santhony.gutierrez@amd.com assert(sizes->readonly_size == 12511308Santhony.gutierrez@amd.com kernels[i]->getSize(HsaCode::MemorySegment::READONLY)); 12611308Santhony.gutierrez@amd.com } 12711308Santhony.gutierrez@amd.com } 12811308Santhony.gutierrez@amd.com 12911308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 13011308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 13111308Santhony.gutierrez@amd.com // add one for terminating '\0' 13211308Santhony.gutierrez@amd.com sizes->string_table_size += k->name().size() + 1; 13311308Santhony.gutierrez@amd.com sizes->code_size += k->numInsts() * sizeof(GPUStaticInst*); 13411308Santhony.gutierrez@amd.com } 13511308Santhony.gutierrez@amd.com 13611308Santhony.gutierrez@amd.com sizes.copyOut(tc->getMemProxy()); 13711308Santhony.gutierrez@amd.com } 13811308Santhony.gutierrez@amd.com break; 13911308Santhony.gutierrez@amd.com 14011308Santhony.gutierrez@amd.com case HSA_GET_KINFO: 14111308Santhony.gutierrez@amd.com { 14211308Santhony.gutierrez@amd.com TypedBufferArg<HsaKernelInfo> 14311308Santhony.gutierrez@amd.com kinfo(buf_addr, sizeof(HsaKernelInfo) * kernels.size()); 14411308Santhony.gutierrez@amd.com 14511308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 14611308Santhony.gutierrez@amd.com HsaKernelInfo *ki = &kinfo[i]; 14711308Santhony.gutierrez@amd.com ki->name_offs = kernelInfo[i].name_offs; 14811308Santhony.gutierrez@amd.com ki->code_offs = kernelInfo[i].code_offs; 14911308Santhony.gutierrez@amd.com ki->sRegCount = kernelInfo[i].sRegCount; 15011308Santhony.gutierrez@amd.com ki->dRegCount = kernelInfo[i].dRegCount; 15111308Santhony.gutierrez@amd.com ki->cRegCount = kernelInfo[i].cRegCount; 15211308Santhony.gutierrez@amd.com ki->static_lds_size = kernelInfo[i].static_lds_size; 15311308Santhony.gutierrez@amd.com ki->private_mem_size = kernelInfo[i].private_mem_size; 15411308Santhony.gutierrez@amd.com ki->spill_mem_size = kernelInfo[i].spill_mem_size; 15511308Santhony.gutierrez@amd.com } 15611308Santhony.gutierrez@amd.com 15711308Santhony.gutierrez@amd.com kinfo.copyOut(tc->getMemProxy()); 15811308Santhony.gutierrez@amd.com } 15911308Santhony.gutierrez@amd.com break; 16011308Santhony.gutierrez@amd.com 16111308Santhony.gutierrez@amd.com case HSA_GET_STRINGS: 16211308Santhony.gutierrez@amd.com { 16311308Santhony.gutierrez@amd.com int string_table_size = 0; 16411308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 16511308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 16611308Santhony.gutierrez@amd.com string_table_size += k->name().size() + 1; 16711308Santhony.gutierrez@amd.com } 16811308Santhony.gutierrez@amd.com 16911308Santhony.gutierrez@amd.com BufferArg buf(buf_addr, string_table_size); 17011308Santhony.gutierrez@amd.com char *bufp = (char*)buf.bufferPtr(); 17111308Santhony.gutierrez@amd.com 17211308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 17311308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 17411308Santhony.gutierrez@amd.com const char *n = k->name().c_str(); 17511308Santhony.gutierrez@amd.com 17611308Santhony.gutierrez@amd.com // idiomatic string copy 17711308Santhony.gutierrez@amd.com while ((*bufp++ = *n++)); 17811308Santhony.gutierrez@amd.com } 17911308Santhony.gutierrez@amd.com 18011308Santhony.gutierrez@amd.com assert(bufp - (char *)buf.bufferPtr() == string_table_size); 18111308Santhony.gutierrez@amd.com 18211308Santhony.gutierrez@amd.com buf.copyOut(tc->getMemProxy()); 18311308Santhony.gutierrez@amd.com } 18411308Santhony.gutierrez@amd.com break; 18511308Santhony.gutierrez@amd.com 18611308Santhony.gutierrez@amd.com case HSA_GET_READONLY_DATA: 18711308Santhony.gutierrez@amd.com { 18811308Santhony.gutierrez@amd.com // we can pick any kernel --- they share the same 18911308Santhony.gutierrez@amd.com // readonly segment (this assumption is checked in GET_SIZES) 19011308Santhony.gutierrez@amd.com uint64_t size = 19111308Santhony.gutierrez@amd.com kernels.back()->getSize(HsaCode::MemorySegment::READONLY); 19211308Santhony.gutierrez@amd.com BufferArg data(buf_addr, size); 19311308Santhony.gutierrez@amd.com char *datap = (char *)data.bufferPtr(); 19411308Santhony.gutierrez@amd.com memcpy(datap, 19511308Santhony.gutierrez@amd.com kernels.back()->readonly_data, 19611308Santhony.gutierrez@amd.com size); 19711308Santhony.gutierrez@amd.com data.copyOut(tc->getMemProxy()); 19811308Santhony.gutierrez@amd.com } 19911308Santhony.gutierrez@amd.com break; 20011308Santhony.gutierrez@amd.com 20111308Santhony.gutierrez@amd.com case HSA_GET_CODE: 20211308Santhony.gutierrez@amd.com { 20311308Santhony.gutierrez@amd.com // set hsaCode pointer 20411308Santhony.gutierrez@amd.com hsaCode = buf_addr; 20511308Santhony.gutierrez@amd.com int code_size = 0; 20611308Santhony.gutierrez@amd.com 20711308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 20811308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 20911308Santhony.gutierrez@amd.com code_size += k->numInsts() * sizeof(TheGpuISA::RawMachInst); 21011308Santhony.gutierrez@amd.com } 21111308Santhony.gutierrez@amd.com 21211308Santhony.gutierrez@amd.com TypedBufferArg<TheGpuISA::RawMachInst> buf(buf_addr, code_size); 21311308Santhony.gutierrez@amd.com TheGpuISA::RawMachInst *bufp = buf; 21411308Santhony.gutierrez@amd.com 21511308Santhony.gutierrez@amd.com int buf_idx = 0; 21611308Santhony.gutierrez@amd.com 21711308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 21811308Santhony.gutierrez@amd.com HsaCode *k = kernels[i]; 21911308Santhony.gutierrez@amd.com 22011308Santhony.gutierrez@amd.com for (int j = 0; j < k->numInsts(); ++j) { 22111308Santhony.gutierrez@amd.com bufp[buf_idx] = k->insts()->at(j); 22211308Santhony.gutierrez@amd.com ++buf_idx; 22311308Santhony.gutierrez@amd.com } 22411308Santhony.gutierrez@amd.com } 22511308Santhony.gutierrez@amd.com 22611308Santhony.gutierrez@amd.com buf.copyOut(tc->getMemProxy()); 22711308Santhony.gutierrez@amd.com } 22811308Santhony.gutierrez@amd.com break; 22911308Santhony.gutierrez@amd.com 23011308Santhony.gutierrez@amd.com case HSA_GET_CU_CNT: 23111308Santhony.gutierrez@amd.com { 23211308Santhony.gutierrez@amd.com BufferArg buf(buf_addr, sizeof(uint32_t)); 23311308Santhony.gutierrez@amd.com *((uint32_t*)buf.bufferPtr()) = dispatcher->getNumCUs(); 23411308Santhony.gutierrez@amd.com buf.copyOut(tc->getMemProxy()); 23511308Santhony.gutierrez@amd.com } 23611308Santhony.gutierrez@amd.com break; 23711308Santhony.gutierrez@amd.com 23811308Santhony.gutierrez@amd.com case HSA_GET_VSZ: 23911308Santhony.gutierrez@amd.com { 24011308Santhony.gutierrez@amd.com BufferArg buf(buf_addr, sizeof(uint32_t)); 24111308Santhony.gutierrez@amd.com *((uint32_t*)buf.bufferPtr()) = VSZ; 24211308Santhony.gutierrez@amd.com buf.copyOut(tc->getMemProxy()); 24311308Santhony.gutierrez@amd.com } 24411308Santhony.gutierrez@amd.com break; 24511308Santhony.gutierrez@amd.com 24611308Santhony.gutierrez@amd.com default: 24711308Santhony.gutierrez@amd.com fatal("ClDriver: bad ioctl %d\n", req); 24811308Santhony.gutierrez@amd.com } 24911308Santhony.gutierrez@amd.com 25011308Santhony.gutierrez@amd.com return 0; 25111308Santhony.gutierrez@amd.com} 25211308Santhony.gutierrez@amd.com 25311308Santhony.gutierrez@amd.comconst char* 25411308Santhony.gutierrez@amd.comClDriver::codeOffToKernelName(uint64_t code_ptr) 25511308Santhony.gutierrez@amd.com{ 25611308Santhony.gutierrez@amd.com assert(hsaCode); 25711308Santhony.gutierrez@amd.com uint32_t code_offs = code_ptr - hsaCode; 25811308Santhony.gutierrez@amd.com 25911308Santhony.gutierrez@amd.com for (int i = 0; i < kernels.size(); ++i) { 26011308Santhony.gutierrez@amd.com if (code_offs == kernelInfo[i].code_offs) { 26111308Santhony.gutierrez@amd.com return kernels[i]->name().c_str(); 26211308Santhony.gutierrez@amd.com } 26311308Santhony.gutierrez@amd.com } 26411308Santhony.gutierrez@amd.com 26511308Santhony.gutierrez@amd.com return nullptr; 26611308Santhony.gutierrez@amd.com} 26711308Santhony.gutierrez@amd.com 26811308Santhony.gutierrez@amd.comClDriver* 26911308Santhony.gutierrez@amd.comClDriverParams::create() 27011308Santhony.gutierrez@amd.com{ 27111308Santhony.gutierrez@amd.com return new ClDriver(this); 27211308Santhony.gutierrez@amd.com} 273