void Kernel::setArgument(unsigned int index, TypedValue value) { assert(index < m_function->arg_size()); const llvm::Value *argument = getArgument(index); // Deallocate existing argument if (m_values.count(argument)) { delete[] m_values[argument].data; } #if LLVM_VERSION >= 40 if (getArgumentTypeName(index).str() == "sampler_t") { // Get an llvm::ConstantInt that represents the sampler value llvm::Type *i32 = llvm::Type::getInt32Ty(m_program->getLLVMContext()); llvm::Constant *samplerValue = llvm::ConstantInt::get(i32, value.getSInt()); // A sampler argument is a pointer to the llvm::ConstantInt value TypedValue sampler; sampler.size = sizeof(size_t); sampler.num = 1; sampler.data = new unsigned char[sizeof(size_t)]; sampler.setPointer((size_t)samplerValue); m_values[argument] = sampler; } else #endif { m_values[argument] = value.clone(); } }
void Program::allocateProgramScopeVars() { deallocateProgramScopeVars(); Memory *globalMemory = m_context->getGlobalMemory(); // Create the pointer values for each global variable llvm::Module::const_global_iterator itr; for (itr = m_module->global_begin(); itr != m_module->global_end(); itr++) { unsigned addrspace = itr->getType()->getPointerAddressSpace(); if (addrspace != AddrSpaceGlobal && addrspace != AddrSpaceConstant) continue; // Allocate global variable const llvm::Type *type = itr->getType()->getPointerElementType(); size_t size = getTypeSize(type); size_t ptr = globalMemory->allocateBuffer(size); m_totalProgramScopeVarSize += size; // Create pointer value TypedValue ptrValue = { sizeof(size_t), 1, new uint8_t[sizeof(size_t)] }; ptrValue.setPointer(ptr); m_programScopeVars[&*itr] = ptrValue; } try { // Initialize global variables for (auto itr = m_programScopeVars.begin(); itr != m_programScopeVars.end(); itr++) { auto var = llvm::cast<llvm::GlobalVariable>(itr->first); const llvm::Constant *initializer = var->getInitializer(); if (!initializer) continue; size_t varptr = itr->second.getPointer(); if (initializer->getType()->getTypeID() == llvm::Type::PointerTyID) { size_t ptr = resolveConstantPointer(initializer, m_programScopeVars); globalMemory->store((uint8_t*)&ptr, varptr, sizeof(size_t)); } else { size_t size = getTypeSize(initializer->getType()); uint8_t *data = new uint8_t[size]; getConstantData((uint8_t*)data, (const llvm::Constant*)initializer); globalMemory->store(data, varptr, size); delete[] data; } } } catch (FatalError& err) { cerr << endl << "OCLGRIND FATAL ERROR " << "(" << err.getFile() << ":" << err.getLine() << ")" << endl << err.what() << endl << "When initializing program scope global variables" << endl; } }
WorkItem::WorkItem(const KernelInvocation *kernelInvocation, WorkGroup *workGroup, Size3 lid) : m_context(kernelInvocation->getContext()), m_kernelInvocation(kernelInvocation), m_workGroup(workGroup) { m_localID = lid; // Compute global ID Size3 groupID = workGroup->getGroupID(); Size3 groupSize = workGroup->getGroupSize(); Size3 globalOffset = kernelInvocation->getGlobalOffset(); m_globalID.x = lid.x + groupID.x*groupSize.x + globalOffset.x; m_globalID.y = lid.y + groupID.y*groupSize.y + globalOffset.y; m_globalID.z = lid.z + groupID.z*groupSize.z + globalOffset.z; Size3 globalSize = kernelInvocation->getGlobalSize(); m_globalIndex = (m_globalID.x + (m_globalID.y + m_globalID.z*globalSize.y) * globalSize.x); const Kernel *kernel = kernelInvocation->getKernel(); // Load interpreter cache m_cache = kernel->getProgram()->getInterpreterCache(kernel->getFunction()); // Set initial number of values to store based on cache m_values.resize(m_cache->getNumValues()); m_privateMemory = new Memory(AddrSpacePrivate, sizeof(size_t)==8 ? 32 : 16, m_context); // Initialise kernel arguments and global variables for (auto value = kernel->values_begin(); value != kernel->values_end(); value++) { pair<unsigned,unsigned> size = getValueSize(value->first); TypedValue v = { size.first, size.second, m_pool.alloc(size.first*size.second) }; const llvm::Type *type = value->first->getType(); if (type->isPointerTy() && type->getPointerAddressSpace() == AddrSpacePrivate) { size_t sz = value->second.size*value->second.num; v.setPointer(m_privateMemory->allocateBuffer(sz, 0, value->second.data)); } else if (type->isPointerTy() && type->getPointerAddressSpace() == AddrSpaceLocal) { v.setPointer(m_workGroup->getLocalMemoryAddress(value->first)); } else { memcpy(v.data, value->second.data, v.size*v.num); } setValue(value->first, v); } // Initialize interpreter state m_state = READY; m_position = new Position; m_position->hasBegun = false; m_position->prevBlock = NULL; m_position->nextBlock = NULL; m_position->currBlock = &*kernel->getFunction()->begin(); m_position->currInst = m_position->currBlock->begin(); }