CommonValues::CommonValues(LContext context) : voidType(FTL::voidType(context)) , boolean(int1Type(context)) , int8(int8Type(context)) , int16(int16Type(context)) , int32(int32Type(context)) , int64(int64Type(context)) , intPtr(intPtrType(context)) , floatType(FTL::floatType(context)) , doubleType(FTL::doubleType(context)) , ref8(pointerType(int8)) , ref16(pointerType(int16)) , ref32(pointerType(int32)) , ref64(pointerType(int64)) , refPtr(pointerType(intPtr)) , refFloat(pointerType(floatType)) , refDouble(pointerType(doubleType)) , booleanTrue(constInt(boolean, true, ZeroExtend)) , booleanFalse(constInt(boolean, false, ZeroExtend)) , int8Zero(constInt(int8, 0, SignExtend)) , int32Zero(constInt(int32, 0, SignExtend)) , int32One(constInt(int32, 1, SignExtend)) , int64Zero(constInt(int64, 0, SignExtend)) , intPtrZero(constInt(intPtr, 0, SignExtend)) , intPtrOne(constInt(intPtr, 1, SignExtend)) , intPtrTwo(constInt(intPtr, 2, SignExtend)) , intPtrThree(constInt(intPtr, 3, SignExtend)) , intPtrFour(constInt(intPtr, 4, SignExtend)) , intPtrEight(constInt(intPtr, 8, SignExtend)) , intPtrPtr(constInt(intPtr, sizeof(void*), SignExtend)) , doubleZero(constReal(doubleType, 0)) , rangeKind(mdKindID(context, "range")) , profKind(mdKindID(context, "prof")) , branchWeights(mdString(context, "branch_weights")) , nonNegativeInt32(constInt(int32, 0, SignExtend), constInt(int32, 1ll << 31, SignExtend)) , m_context(context) , m_module(0) { }
bool compile(const nstr& name, NNet& network, size_t threads){ RunNetwork* runNetwork = new RunNetwork; NNet::Layer* inputLayer = network.layer(0); size_t numLayers = network.numLayers(); RunLayer* lastRunLayer = 0; for(size_t l = 1; l < numLayers; ++l){ RunLayer* runLayer = new RunLayer; runLayer->queue = new Queue(threads); size_t inputLayerSize = inputLayer->size(); NNet::Layer* layer = network.layer(l); size_t layerSize = layer->size(); if(l > 1){ runLayer->inputVecStart = lastRunLayer->outputVecStart; runLayer->inputVec = lastRunLayer->outputVec; } if(l < numLayers - 1){ double* outputVecPtrStart; double* outputVecPtr; allocVector(layerSize, &outputVecPtrStart, &outputVecPtr); runLayer->outputVecStart = outputVecPtrStart; runLayer->outputVec = outputVecPtr; } TypeVec args; args.push_back(getPointer(doubleVecType(inputLayerSize))); args.push_back(getPointer(doubleVecType(inputLayerSize))); args.push_back(getPointer(doubleType())); args.push_back(int32Type()); FunctionType* ft = FunctionType::get(voidType(), args, false); Function* f = Function::Create(ft, Function::ExternalLinkage, name.c_str(), &module_); BasicBlock* entry = BasicBlock::Create(context_, "entry", f); builder_.SetInsertPoint(entry); auto aitr = f->arg_begin(); Value* inputVecPtr = aitr; inputVecPtr->setName("input_vec_ptr"); ++aitr; Value* weightVecPtr = aitr; weightVecPtr->setName("weight_vec_ptr"); ++aitr; Value* outputVecPtr = aitr; outputVecPtr->setName("output_vec_ptr"); ++aitr; Value* outputIndex = aitr; outputIndex->setName("output_index"); Value* inputVec = builder_.CreateLoad(inputVecPtr, "input_vec"); Value* weightVec = builder_.CreateLoad(weightVecPtr, "weight_vec"); Value* mulVec = builder_.CreateFMul(inputVec, weightVec, "mul_vec"); Value* sumActivation = builder_.CreateExtractElement(mulVec, getInt32(0), "sum_elem"); for(size_t i = 1; i < inputLayerSize; ++i){ Value* elem = builder_.CreateExtractElement(mulVec, getInt32(i), "sum_elem"); sumActivation = builder_.CreateFAdd(sumActivation, elem, "sum_activation"); } Value* output = getActivationOutput(layer->neuron(0), sumActivation); Value* outputElement = builder_.CreateGEP(outputVecPtr, outputIndex, "out_elem"); builder_.CreateStore(output, outputElement); builder_.CreateRetVoid(); runLayer->f = f; runLayer->fp = (void (*)(void*, void*, void*, int)) engine_->getPointerToFunction(f); for(size_t j = 0; j < layerSize; ++j){ NNet::Neuron* nj = layer->neuron(j); RunNeuron* runNeuron = new RunNeuron; runNeuron->layer = runLayer; runNeuron->outputIndex = j; double* weightVecPtrStart; double* weightVecPtr; allocVector(inputLayerSize, &weightVecPtrStart, &weightVecPtr); runNeuron->weightVecStart = weightVecPtrStart; runNeuron->weightVec = weightVecPtr; for(size_t i = 0; i < inputLayerSize; ++i){ NNet::Neuron* ni = inputLayer->neuron(i); weightVecPtr[i] = nj->weight(ni); } runLayer->queue->add(runNeuron); } runNetwork->layerVec.push_back(runLayer); inputLayer = layer; lastRunLayer = runLayer; } networkMap_.insert(make_pair(name, runNetwork)); return true; }