bool
TargetNVC0::isModSupported(const Instruction *insn, int s, Modifier mod) const
{
   if (!isFloatType(insn->dType)) {
      switch (insn->op) {
      case OP_ABS:
      case OP_NEG:
      case OP_CVT:
      case OP_CEIL:
      case OP_FLOOR:
      case OP_TRUNC:
      case OP_AND:
      case OP_OR:
      case OP_XOR:
         break;
      case OP_ADD:
         if (mod.abs())
            return false;
         if (insn->src(s ? 0 : 1).mod.neg())
            return false;
         break;
      case OP_SUB:
         if (s == 0)
            return insn->src(1).mod.neg() ? false : true;
         break;
      default:
         return false;
      }
   }
   if (s > 3)
      return false;
   return (mod & Modifier(opInfo[insn->op].srcMods[s])) == mod;
}
Esempio n. 2
0
PyType PyType::lookupType(const std::string &typeNameIn, ULONG64 module)
{
    if (debuggingTypeEnabled())
        DebugPrint() << "lookup type '" << typeNameIn << "'";
    std::string typeName = typeNameIn;
    trimBack(typeName);
    trimFront(typeName);

    if (isPointerType(typeName) || isArrayType(typeName))
        return PyType(0, 0, typeName);

    if (typeName.find("enum ") == 0)
        typeName.erase(0, 5);
    if (endsWith(typeName, " const"))
        typeName.erase(typeName.length() - 6);
    if (typeName == "__int64" || typeName == "unsigned __int64")
        typeName.erase(typeName.find("__"), 2);

    const static std::regex typeNameRE("^[a-zA-Z_][a-zA-Z0-9_]*!?[a-zA-Z0-9_<>:, \\*\\&\\[\\]]*$");
    if (!std::regex_match(typeName, typeNameRE))
        return PyType();

    CIDebugSymbols *symbols = ExtensionCommandContext::instance()->symbols();
    ULONG typeId;
    HRESULT result = S_FALSE;
    if (module != 0 && !isIntegralType(typeName) && !isFloatType(typeName))
        result = symbols->GetTypeId(module, typeName.c_str(), &typeId);
    if (FAILED(result) || result == S_FALSE)
        result = symbols->GetSymbolTypeId(typeName.c_str(), &typeId, &module);
    if (FAILED(result))
        return createUnresolvedType(typeName);
    return PyType(module, typeId, typeName);

}
Esempio n. 3
0
//--------------------------------------------------------------
bool  ofxMuiNumberData::addValue(float val, ofxMuiRange _bounds, ofxMuiRange _range) {

    // prepare iterators
    // start inserting
    historyLength.push_back(_defaults->dataHistoryLength);
    deque<float> initQ(_defaults->dataHistoryLength, val); // create a history
    values.push_back(initQ); // add the queue
    
    bounds.push_back(_bounds);
    ranges.push_back(_range);

    displayPrecision.push_back(_defaults->displayPrecision);


    if(isBoolType() || isIntType()) {
        incrementValues.push_back(_defaults->incrementInt);
    } else if(isFloatType()) {
        incrementValues.push_back(_defaults->incrementFloat);
    }

    bool boundsChanged = false;
    bool rangeChanged = false;
    bool valueChanged = false;
    checkRange(boundsChanged, rangeChanged, getNumValues()-1);
    constrainValue(valueChanged, getNumValues()-1);

}
Esempio n. 4
0
std::string PyType::name(bool withModule) const
{
    if (m_name.empty()) {
        auto symbols = ExtensionCommandContext::instance()->symbols();
        ULONG size = 0;
        symbols->GetTypeName(m_module, m_typeId, NULL, 0, &size);
        if (size == 0)
            return std::string();

        std::string typeName(size - 1, '\0');
        if (FAILED(symbols->GetTypeName(m_module, m_typeId, &typeName[0], size, &size)))
            return std::string();

        m_name = typeName;
    }

    if (withModule && !isIntegralType(m_name) && !isFloatType(m_name)) {
        std::string completeName = module();
        if (!completeName.empty())
            completeName.append("!");
        completeName.append(m_name);
        return completeName;
    }

    return m_name;
}
Esempio n. 5
0
File: Tag.cpp Progetto: Gjum/NBT-Cpp
 // gets the ith item of a number list
 // 0.0 if no such type or out of bounds
 double Tag::getListItemAsFloat(int32_t i) const {
     if (isIntType(payload->tagList.type))
         return payload->tagList.values->at(i)->tagInt;
     if (isFloatType(payload->tagList.type))
         return payload->tagList.values->at(i)->tagFloat;
     return 0.0;
 }
Esempio n. 6
0
File: Tag.cpp Progetto: Gjum/NBT-Cpp
 // get value as string
 // might contain '\n' if list or compound
 std::string Tag::asString() const {
     if (isIntType(type)) return std::to_string(payload->tagInt);
     else if (isFloatType(type)) return std::to_string(payload->tagFloat);
     else if (type == tagTypeString) return *payload->tagString;
     else if (isListType(type) || type == tagTypeCompound) {
         std::string str = std::to_string(getListSize()) + " entries\n{\n";
         for (int32_t i = 0; i < getListSize(); i++) {
             // limit output to 10-15 lines
             if (isListType(type) && i >= 10 && getListSize() > 15) {
                 str += "  ... and " + std::to_string(getListSize()-10) + " more\n";
                 break;
             }
             Tag * tag = getListItemAsTag(i);
             if (tag != NULL) {
                 std::string content = "  " + tag->toString();
                 // indent content
                 for (size_t pos = content.find_first_of('\n'); pos != std::string::npos; pos = content.find_first_of('\n', pos+1)) {
                     content = content.replace(pos, 1, "\n  ");
                 }
                 str += content + "\n";
             }
             else str += "  ERROR\n";
         }
         str += "}";
         return str;
     }
     return "";
 }
Esempio n. 7
0
bool
TargetNV50::isOpSupported(operation op, DataType ty) const
{
   if (ty == TYPE_F64 && chipset < 0xa0)
      return false;

   switch (op) {
   case OP_PRERET:
      return chipset >= 0xa0;
   case OP_TXG:
      return chipset >= 0xa3 && chipset != 0xaa && chipset != 0xac;
   case OP_POW:
   case OP_SQRT:
   case OP_DIV:
   case OP_MOD:
   case OP_SET_AND:
   case OP_SET_OR:
   case OP_SET_XOR:
   case OP_SLCT:
   case OP_SELP:
   case OP_POPCNT:
   case OP_INSBF:
   case OP_EXTBF:
   case OP_EXIT: // want exit modifier instead (on NOP if required)
   case OP_MEMBAR:
      return false;
   case OP_SAD:
      return ty == TYPE_S32;
   case OP_SET:
      return !isFloatType(ty);
   default:
      return true;
   }
}
Esempio n. 8
0
File: Tag.cpp Progetto: Gjum/NBT-Cpp
 // gets the ith item of a list as string
 // "" if out of bounds
 // may contain '\n' if list or compound
 std::string Tag::getListItemAsString(int32_t i) const {
     if (isIntType(payload->tagList.type))
         return std::to_string(payload->tagList.values->at(i)->tagInt);
     if (isFloatType(payload->tagList.type))
         return std::to_string(payload->tagList.values->at(i)->tagFloat);
     if (payload->tagList.type == tagTypeString)
         return *payload->tagList.values->at(i)->tagString;
     // no primitive type, use Tag::asString()
     Tag * tag = getListItemAsTag(i);
     if (tag) {
         std::string str = tag->asString();
         delete tag;
         return str;
     }
     return "";
 }
Esempio n. 9
0
int PyType::code() const
{
    if (!m_resolved)
        return TypeCodeUnresolvable;

    if (m_tag < 0) {
        // try to parse typeName
        const std::string &typeName = name();
        if (typeName.empty())
            return TypeCodeUnresolvable;
        if (isPointerType(typeName))
            return TypeCodePointer;
        if (isArrayType(typeName))
            return TypeCodeArray;
        if (typeName.find("<function>") == 0)
            return TypeCodeFunction;
        if (isIntegralType(typeName))
            return TypeCodeIntegral;
        if (isFloatType(typeName))
            return TypeCodeFloat;

        IDebugSymbolGroup2 *sg = 0;
        if (FAILED(ExtensionCommandContext::instance()->symbols()->CreateSymbolGroup2(&sg)))
            return TypeCodeStruct;

        if (knownType(name(), 0) != KT_Unknown)
            return TypeCodeStruct;

        const std::string helperValueName = SymbolGroupValue::pointedToSymbolName(0, name(true));
        ULONG index = DEBUG_ANY_ID;
        if (SUCCEEDED(sg->AddSymbol(helperValueName.c_str(), &index)))
            m_tag = PyValue(index, sg).tag();
        sg->Release();
    }
    switch (m_tag) {
    case SymTagUDT: return TypeCodeStruct;
    case SymTagEnum: return TypeCodeEnum;
    case SymTagTypedef: return TypeCodeTypedef;
    case SymTagFunctionType: return TypeCodeFunction;
    case SymTagPointerType: return TypeCodePointer;
    case SymTagArrayType: return TypeCodeArray;
    case SymTagBaseType: return isIntegralType(name()) ? TypeCodeIntegral : TypeCodeFloat;
    default: break;
    }

    return TypeCodeStruct;
}
Esempio n. 10
0
//--------------------------------------------------------------
bool  ofxMuiNumberData::insertValue(int index, float val, ofxMuiRange _bounds, ofxMuiRange _range) {
    if(isValidInsertionIndex(index)) {
        // prepare iterators
        valuesIter = values.begin() + index;
        historyLengthIter = historyLength.begin() + index;
        boundsIter = bounds.begin() + index;
        rangesIter = ranges.begin() + index;
        displayPrecisionIter = displayPrecision.begin() + index; 
        incrementValuesIter = incrementValues.begin() + index;
        
        // start inserting
        
        historyLength.insert(historyLengthIter, _defaults->dataHistoryLength);
        deque<float> initQ(_defaults->dataHistoryLength, val); // create a history
        values.push_back(initQ); // add the queue
        values.insert(valuesIter, initQ);

        bounds.insert(boundsIter, _bounds);
        ranges.insert(rangesIter, _range);
        
        // if it's global, take it from the other
        displayPrecision.insert(displayPrecisionIter, _defaults->displayPrecision);
        
        
        if(isBoolType() || isIntType()) {
            incrementValues.insert(incrementValuesIter, _defaults->incrementInt);
        } else if(isFloatType()) {
            incrementValues.insert(incrementValuesIter, _defaults->incrementFloat);
        }
        
        bool boundsChanged = false;
        bool rangeChanged = false;
        bool valueChanged = false;        
        checkRange(boundsChanged, rangeChanged, index);
        constrainValue(valueChanged,index);
        
    } else {
        return false;
    }
}
bool
TargetGM107::isOpSupported(operation op, DataType ty) const
{
   switch (op) {
   case OP_SAD:
   case OP_POW:
   case OP_DIV:
   case OP_MOD:
      return false;
   case OP_SQRT:
      if (ty == TYPE_F64)
         return false;
      return chipset >= NVISA_GM200_CHIPSET;
   case OP_XMAD:
      if (isFloatType(ty))
         return false;
      break;
   default:
      break;
   }

   return true;
}
Esempio n. 12
0
// long:  rrr, arr, rcr, acr, rrc, arc, gcr, grr
// short: rr, ar, rc, gr
// immd:  ri, gi
bool
TargetNV50::insnCanLoad(const Instruction *i, int s,
                        const Instruction *ld) const
{
   DataFile sf = ld->src(0).getFile();

   if (sf == FILE_IMMEDIATE && (i->predSrc >= 0 || i->flagsDef >= 0))
      return false;
   if (s >= opInfo[i->op].srcNr)
      return false;
   if (!(opInfo[i->op].srcFiles[s] & (1 << (int)sf)))
      return false;
   if (s == 2 && i->src(1).getFile() != FILE_GPR)
      return false;

   // NOTE: don't rely on flagsDef
   for (int d = 0; i->defExists(d); ++d)
      if (i->def(d).getFile() == FILE_FLAGS)
         return false;

   unsigned mode = 0;

   for (int z = 0; z < Target::operationSrcNr[i->op]; ++z) {
      DataFile zf = (z == s) ? sf : i->src(z).getFile();
      switch (zf) {
      case FILE_GPR:
         break;
      case FILE_MEMORY_SHARED:
      case FILE_SHADER_INPUT:
         mode |= 1 << (z * 2);
         break;
      case FILE_MEMORY_CONST:
         mode |= 2 << (z * 2);
         break;
      case FILE_IMMEDIATE:
         mode |= 3 << (z * 2);
      default:
         break;
      }
   }

   switch (mode) {
   case 0x00:
   case 0x01:
   case 0x03:
   case 0x08:
   case 0x09:
   case 0x0c:
   case 0x20:
   case 0x21:
      break;
   case 0x0d:
      if (ld->bb->getProgram()->getType() != Program::TYPE_GEOMETRY)
         return false;
   default:
      return false;
   }

   uint8_t ldSize;

   if ((i->op == OP_MUL || i->op == OP_MAD) && !isFloatType(i->dType)) {
      // 32-bit MUL will be split into 16-bit MULs
      if (ld->src(0).isIndirect(0))
         return false;
      if (sf == FILE_IMMEDIATE)
         return false;
      ldSize = 2;
   } else {
      ldSize = typeSizeof(ld->dType);
   }

   if (sf == FILE_IMMEDIATE)
      return true;


   // Check if memory access is encodable:

   if (ldSize < 4 && sf == FILE_SHADER_INPUT) // no < 4-byte aligned a[] access
      return false;
   if (ld->getSrc(0)->reg.data.offset > (int32_t)(127 * ldSize))
      return false;

   if (ld->src(0).isIndirect(0)) {
      for (int z = 0; i->srcExists(z); ++z)
         if (i->src(z).isIndirect(0))
            return false;

      // s[] access only possible in CP, $aX always applies
      if (sf == FILE_MEMORY_SHARED)
         return true;
      if (!ld->bb) // can't check type ...
         return false;
      Program::Type pt = ld->bb->getProgram()->getType();

      // $aX applies to c[] only in VP, FP, GP if p[] is not accessed
      if (pt == Program::TYPE_COMPUTE)
         return false;
      if (pt == Program::TYPE_GEOMETRY) {
         if (sf == FILE_MEMORY_CONST)
            return i->src(s).getFile() != FILE_SHADER_INPUT;
         return sf == FILE_SHADER_INPUT;
      }
      return sf == FILE_MEMORY_CONST;
   }
   return true;
}
Esempio n. 13
0
llvm::Value* genFloatPrimitiveMethodCall(Function& function, const SEM::Type* type, const String& methodName, const SEM::FunctionType functionType,
        llvm::ArrayRef<SEM::Value> templateArgs, PendingResultArray args, llvm::Value* const hintResultValue) {
    auto& module = function.module();
    auto& builder = function.getBuilder();

    const auto& typeName = type->getObjectType()->name().first();

    const auto methodID = module.context().getMethodID(CanonicalizeMethodName(methodName));

    const auto methodOwner = methodID.isConstructor() ? nullptr : args[0].resolveWithoutBind(function);

    if (methodName == "__move_to") {
        const auto moveToPtr = args[1].resolve(function);
        const auto moveToPosition = args[2].resolve(function);

        const auto destPtr = builder.CreateInBoundsGEP(moveToPtr, moveToPosition);
        const auto castedDestPtr = builder.CreatePointerCast(destPtr, genPointerType(module, type));

        genMoveStore(function, methodOwner, castedDestPtr, type);
        return ConstantGenerator(module).getVoidUndef();
    } else if (methodName == "create") {
        return ConstantGenerator(module).getPrimitiveFloat(typeName, 0.0);
    } else if (methodName == "__setdead" || methodName == "__set_dead") {
        // Do nothing.
        return ConstantGenerator(module).getVoidUndef();
    } else if (methodName == "__islive" || methodName == "__is_live") {
        return ConstantGenerator(module).getI1(true);
    } else if (methodName.starts_with("implicit_cast_") || methodName.starts_with("cast_")) {
        const auto argType = functionType.parameterTypes().front();
        const auto operand = args[0].resolve(function);
        const auto selfType = genType(module, type);
        if (isFloatType(module, argType)) {
            if (methodName.starts_with("implicit_cast_")) {
                return builder.CreateFPExt(operand, selfType);
            } else {
                return builder.CreateFPTrunc(operand, selfType);
            }
        } else if (isUnsignedIntegerType(module, argType)) {
            return builder.CreateUIToFP(operand, selfType);
        } else if (isSignedIntegerType(module, argType)) {
            return builder.CreateSIToFP(operand, selfType);
        } else {
            llvm_unreachable("Unknown float cast source type.");
        }
    } else if (isUnaryOp(methodName)) {
        const auto zero = ConstantGenerator(module).getPrimitiveFloat(typeName, 0.0);

        if (methodName == "implicit_cast" || methodName == "cast") {
            return callCastMethod(function, methodOwner, type, methodName, templateArgs.front().typeRefType(), hintResultValue);
        } else if (methodName == "implicit_copy" || methodName == "copy" || methodName == "plus") {
            return methodOwner;
        } else if (methodName == "minus") {
            return builder.CreateFNeg(methodOwner);
        } else if (methodName == "isZero") {
            return builder.CreateFCmpOEQ(methodOwner, zero);
        } else if (methodName == "isPositive") {
            return builder.CreateFCmpOGT(methodOwner, zero);
        } else if (methodName == "isNegative") {
            return builder.CreateFCmpOLT(methodOwner, zero);
        } else if (methodName == "abs") {
            // Generates: (value < 0) ? -value : value.
            const auto lessThanZero = builder.CreateFCmpOLT(methodOwner, zero);
            return builder.CreateSelect(lessThanZero, builder.CreateFNeg(methodOwner), methodOwner);
        } else if (methodName == "sqrt") {
            llvm::Type* const intrinsicTypes[] = { methodOwner->getType() };
            const auto sqrtIntrinsic = llvm::Intrinsic::getDeclaration(module.getLLVMModulePtr(), llvm::Intrinsic::sqrt, intrinsicTypes);
            llvm::Value* const sqrtArgs[] = { methodOwner };
            return builder.CreateCall(sqrtIntrinsic, sqrtArgs);
        } else {
            llvm_unreachable("Unknown primitive unary op.");
        }
    } else if (isBinaryOp(methodName)) {
        const auto operand = args[1].resolveWithoutBind(function);

        if (methodName == "add") {
            return builder.CreateFAdd(methodOwner, operand);
        } else if (methodName == "subtract") {
            return builder.CreateFSub(methodOwner, operand);
        } else if (methodName == "multiply") {
            return builder.CreateFMul(methodOwner, operand);
        } else if (methodName == "divide") {
            return builder.CreateFDiv(methodOwner, operand);
        } else if (methodName == "modulo") {
            return builder.CreateFRem(methodOwner, operand);
        } else if (methodName == "equal") {
            return builder.CreateFCmpOEQ(methodOwner, operand);
        } else if (methodName == "not_equal") {
            return builder.CreateFCmpONE(methodOwner, operand);
        } else if (methodName == "less_than") {
            return builder.CreateFCmpOLT(methodOwner, operand);
        } else if (methodName == "less_than_or_equal") {
            return builder.CreateFCmpOLE(methodOwner, operand);
        } else if (methodName == "greater_than") {
            return builder.CreateFCmpOGT(methodOwner, operand);
        } else if (methodName == "greater_than_or_equal") {
            return builder.CreateFCmpOGE(methodOwner, operand);
        } else if (methodName == "compare") {
            const auto isLessThan = builder.CreateFCmpOLT(methodOwner, operand);
            const auto isGreaterThan = builder.CreateFCmpOGT(methodOwner, operand);
            const auto minusOne = ConstantGenerator(module).getI8(-1);
            const auto zero = ConstantGenerator(module).getI8(0);
            const auto plusOne = ConstantGenerator(module).getI8(1);
            return builder.CreateSelect(isLessThan, minusOne,
                                        builder.CreateSelect(isGreaterThan, plusOne, zero));
        } else {
            llvm_unreachable("Unknown primitive binary op.");
        }
    } else {
        printf("%s\n", methodName.c_str());
        llvm_unreachable("Unknown primitive method.");
    }
}
// Return true when an instruction requires to set up a barrier because it
// doesn't operate at a fixed latency. Variable latency instructions are memory
// operations, double precision operations, special function unit operations
// and other low throughput instructions.
bool
TargetGM107::isBarrierRequired(const Instruction *insn) const
{
   const OpClass cl = getOpClass(insn->op);

   if (insn->dType == TYPE_F64 || insn->sType == TYPE_F64)
      return true;

   switch (cl) {
   case OPCLASS_ATOMIC:
   case OPCLASS_LOAD:
   case OPCLASS_STORE:
   case OPCLASS_SURFACE:
   case OPCLASS_TEXTURE:
      return true;
   case OPCLASS_SFU:
      switch (insn->op) {
      case OP_COS:
      case OP_EX2:
      case OP_LG2:
      case OP_LINTERP:
      case OP_PINTERP:
      case OP_RCP:
      case OP_RSQ:
      case OP_SIN:
      case OP_SQRT:
         return true;
      default:
         break;
      }
      break;
   case OPCLASS_BITFIELD:
      switch (insn->op) {
      case OP_BFIND:
      case OP_POPCNT:
         return true;
      default:
         break;
      }
      break;
   case OPCLASS_CONTROL:
      switch (insn->op) {
      case OP_EMIT:
      case OP_RESTART:
         return true;
      default:
         break;
      }
      break;
   case OPCLASS_OTHER:
      switch (insn->op) {
      case OP_AFETCH:
      case OP_PFETCH:
      case OP_PIXLD:
      case OP_SHFL:
         return true;
      case OP_RDSV:
         return !isCS2RSV(insn->getSrc(0)->reg.data.sv.sv);
      default:
         break;
      }
      break;
   case OPCLASS_ARITH:
      if ((insn->op == OP_MUL || insn->op == OP_MAD) &&
          !isFloatType(insn->dType))
         return true;
      break;
   case OPCLASS_CONVERT:
      if (insn->def(0).getFile() != FILE_PREDICATE &&
          insn->src(0).getFile() != FILE_PREDICATE)
         return true;
      break;
   default:
      break;
   }
   return false;
}
Esempio n. 15
0
bool isIntOrFloatType(const QByteArray &type)
{
    return isIntType(type) || isFloatType(type);
}
Esempio n. 16
0
bool OpenCLParser::convert(std::string fileNameIN, std::string fileNameOUT) {

	if ( access( fileNameIN.c_str(), F_OK ) == -1 ) {
		LOG(ERROR) << "kernel source file = '" << fileNameIN.c_str() << "' doesn't exist";
		return false;
	}

	if ( access( fileNameIN.c_str(), R_OK ) == -1 ) {
		LOG(ERROR) << "kernel source file = '" << fileNameIN.c_str() << "' isn't readable";
		return false;
	}

	if ( access( fileNameOUT.c_str(), F_OK ) == 0 ) {

		 struct stat statIN;
		 if (stat(fileNameIN.c_str(), &statIN) == -1) {
		       perror(fileNameIN.c_str());
		       return false;
		 }

		 struct stat statOUT;
		 if (stat(fileNameOUT.c_str(), &statOUT) == -1) {
		       perror(fileNameOUT.c_str());
		       return false;
		 }

		 if ( statOUT.st_mtime > statIN.st_mtime ) {
			 DLOG(INFO) << "kernel source file = '" << fileNameOUT.c_str() << "' up-to-date";
			 return true;
		 }
	}

	std::ifstream file;
	file.open(fileNameIN.c_str(), std::ifstream::in );
	if ( ! file.is_open() ) {
		LOG(ERROR) << "failed to open file = '" << fileNameIN.c_str() << "' for reading";
		return false;
	}

    std::string line;
    std::string kernel_buffer;
    std::string kernel_name;
    std::string kernel_type;
    std::string kernel_name_typed;
    std::string kernel_line_typed;
    std::string kernel_modified;
    std::string type_replace;
    std::string stdOpenCL;

    stdOpenCL += "// This file was auto-generated from file '" + fileNameIN + "' to conform to standard OpenCL\n";

    bool recording = false;

    while (std::getline(file, line)) {

    	if ( isAttributeLine(line) ) {
    		if ( recording ) {
          		recording = false;
       		}
        	kernel_name_typed = getTypedKernelName(line);
        	kernel_line_typed = "__kernel void " + kernel_name_typed + getTypedKernelLine(line) + " {";

        	if ( isFloatType(kernel_name_typed) ) {
        		type_replace = "float";
        	}
        	if ( isDoubleType(kernel_name_typed) ) {
        		type_replace = "double";
        	}

        	kernel_modified = kernel_line_typed + "\n" + kernel_buffer;

       		boost::regex re;
       		re = boost::regex("\\sT\\s", boost::regex::perl);
       		kernel_modified = boost::regex_replace(kernel_modified, re, " "+type_replace+" ");

       		re = boost::regex("\\sT\\*\\s", boost::regex::perl);
       		kernel_modified = boost::regex_replace(kernel_modified, re, " "+type_replace+"* ");

        	stdOpenCL += kernel_modified;
        	continue;
    	}

    	if ( isTemplateKernelLine(line) ) {
    		kernel_name = getKernelName(line);
    		kernel_type = getKernelType(line);
        DLOG(INFO)<<"found template kernel '"<<kernel_name<<"' with type '"<<kernel_type<<"'";

        	if ( recording == false ) {
        		recording = true;
        	} else {
        		LOG(ERROR) << "error parsing kernel source file = '" << fileNameIN.c_str() << "'";
        		return false;
        	}
        	continue;
    	}

    	if ( recording ) {
    		kernel_buffer += line + "\n";
    	} else {
        	kernel_buffer = "";
        	stdOpenCL += line + "\n";
    	}

    }

    std::ofstream out(fileNameOUT.c_str());
    out << stdOpenCL;
    out.close();
    DLOG(INFO) << "convert AMD OpenCL '"<<fileNameIN.c_str()<<"' to standard OpenCL '"<<fileNameOUT.c_str()<<"'";
	return true;
}