Added default module launch api functionality

1. As in hipModuleLaunchKernel(..., kernelParams, nullptr); works with this commit
    2. Added headers AMDGPUPTNote.h, AMDGPURuntimeMetadata.h to do code object meta data parsing
    3. Changed CMake to look at llvm link libraries
    4. HIP developer should set env variable LLVM_HOME to remove link errors
    5. HIP depends on installed LLVM (not source, not build)
    6. Added sample to test out the feature
    7. Right now HCC does not support embedding metadata in code object. Use clang opencl
    8. Changed HIPCC to read LLVM_HOME env var
    9. New argument to CMake should be given -DLLVM_HOME=<where llvm 5.0 is installed>

Change-Id: Iba38194aa872d97cc2c90a8e5ff746c48055c868
Cette révision appartient à :
Aditya Atluri
2017-03-17 13:11:34 -05:00
Parent 8cbe310870
révision 99432cc12c
10 fichiers modifiés avec 553 ajouts et 12 suppressions
+95 -4
Voir le fichier
@@ -23,7 +23,12 @@ THE SOFTWARE.
#include <fstream>
#include <stdio.h>
#include <stdlib.h>
#include <libelf.h>
#include <elf.h>
#include <gelf.h>
#include <map>
#include "AMDGPUPTNote.h"
#include "AMDGPURuntimeMetadata.h"
#include "hsa/hsa.h"
#include "hsa/hsa_ext_amd.h"
@@ -35,6 +40,30 @@ THE SOFTWARE.
//TODO Use Pool APIs from HCC to get memory regions.
#include <cassert>
inline uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew = 0) {
assert(Align != 0u && "Align can't be 0.");
Skew %= Align;
return (Value + Align - 1 - Skew) / Align * Align + Skew;
}
struct ihipKernArgInfo{
std::vector<uint32_t> Size;
std::vector<uint32_t> Align;
std::vector<std::string> ArgType;
std::vector<std::string> ArgName;
uint32_t totalSize;
};
std::map<std::string,struct ihipKernArgInfo> kernelArguments;
struct MyElfNote {
uint32_t n_namesz = 0;
uint32_t n_descsz = 0;
uint32_t n_type = 0;
MyElfNote() = default;
};
struct ihipModuleSymbol_t{
uint64_t _object; // The kernel object.
@@ -172,8 +201,56 @@ hipError_t hipModuleLoad(hipModule_t *module, const char *fname){
(*module)->ptr = p;
(*module)->size = size;
in.seekg(0, std::ios::beg);
std::copy(std::istreambuf_iterator<char>(in),
std::istreambuf_iterator<char>(), ptr);
std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), ptr);
Elf *e = elf_memory((char*)p, size);
if(elf_kind(e) != ELF_K_ELF){
return ihipLogStatus(hipErrorInvalidValue);
}
size_t numpHdrs;
if(elf_getphdrnum(e, &numpHdrs) != 0){
return ihipLogStatus(hipErrorInvalidValue);
}
for(size_t i=0;i<numpHdrs;i++){
GElf_Phdr pHdr;
if(gelf_getphdr(e, i, &pHdr) != &pHdr){
continue;
}
if(pHdr.p_type == PT_NOTE && pHdr.p_align >= sizeof(int)){
char* ptr = (char*) p + pHdr.p_offset;
char* segmentEnd = ptr + pHdr.p_filesz;
while(ptr < segmentEnd){
MyElfNote *note = (MyElfNote*) ptr;
char *name = (char*) &note[1];
char *desc = name + alignTo(note->n_namesz, sizeof(int));
if (note->n_type == 8) {
std::string metadatastr((const char*)desc, (size_t)note->n_descsz);
AMDGPU::RuntimeMD::Program::Metadata meta;
meta = meta.fromYAML(metadatastr);
for(int i=0;i<meta.Kernels.size();i++){
struct ihipKernArgInfo pl;
size_t totalSizeOfArgs = 0;
for(int j=0;j<meta.Kernels[i].Args.size();j++){
if(meta.Kernels[i].Args[j].Kind < 7) {
pl.Size.push_back(meta.Kernels[i].Args[j].Size);
pl.Align.push_back(meta.Kernels[i].Args[j].Align);
pl.ArgType.push_back(meta.Kernels[i].Args[j].TypeName);
pl.ArgName.push_back(meta.Kernels[i].Args[j].Name);
totalSizeOfArgs += meta.Kernels[i].Args[j].Align;
}
}
pl.totalSize = totalSizeOfArgs;
kernelArguments[meta.Kernels[i].Name] = pl;
}
break;
}
ptr += sizeof(*note)
+ alignTo(note->n_namesz, sizeof(int))
+ alignTo(note->n_descsz, sizeof(int));
}
}
}
status = hsa_code_object_deserialize(ptr, size, NULL, &(*module)->object);
@@ -313,7 +390,19 @@ hipError_t hipModuleLaunchKernel(hipFunction_t f,
void *config[5] = {0};
size_t kernArgSize;
if(extra != NULL){
if(kernelParams != NULL){
std::string name = f->_name;
struct ihipKernArgInfo pl = kernelArguments[name];
char* argBuf = (char*)malloc(pl.totalSize);
memset(argBuf, 0, pl.totalSize);
int index = 0;
for(int i=0;i<pl.Size.size();i++){
memcpy(argBuf + index, kernelParams[i], pl.Size[i]);
index += pl.Align[i];
}
config[1] = (void*)argBuf;
kernArgSize = pl.totalSize;
} else if(extra != NULL){
memcpy(config, extra, sizeof(size_t)*5);
if(config[0] == HIP_LAUNCH_PARAM_BUFFER_POINTER && config[2] == HIP_LAUNCH_PARAM_BUFFER_SIZE && config[4] == HIP_LAUNCH_PARAM_END){
kernArgSize = *(size_t*)(config[3]);
@@ -364,7 +453,9 @@ hipError_t hipModuleLaunchKernel(hipFunction_t f,
lp.av->dispatch_hsa_kernel(&aql, config[1] /* kernarg*/, kernArgSize, nullptr/*completion_future*/);
if(kernelParams != NULL){
free(config[1]);
}
ihipPostLaunchKernel(f->_name.c_str(), hStream, lp);
}