template <class T> U32 hashArray(const T* ptr, int size) { FW_ASSERT(size >= 0); FW_ASSERT(ptr || !size); U32 a = FW_HASH_MAGIC; U32 b = FW_HASH_MAGIC; U32 c = FW_HASH_MAGIC; while (size >= 3) { a += hash<T>(ptr[0]); b += hash<T>(ptr[1]); c += hash<T>(ptr[2]); FW_JENKINS_MIX(a, b, c); ptr += 3; size -= 3; } switch (size) { case 2: b += hash<T>(ptr[1]); case 1: a += hash<T>(ptr[0]); } c += size; FW_JENKINS_MIX(a, b, c); return c; }
U64 CudaCompiler::getMemHash(void) { if (m_memHashValid) { return m_memHash; } if (!m_sourceFileHashValid) { m_sourceFileHash = hash<std::string>(m_sourceFile); m_sourceFileHashValid = true; } if (!m_optionHashValid) { m_optionHash = hash<std::string>(m_options); m_optionHashValid = true; } if (!m_defineHashValid) { U32 a = FW_HASH_MAGIC, b = FW_HASH_MAGIC, c = FW_HASH_MAGIC; DefinesMap_t::iterator it; for (it = m_defines.begin(); it != m_defines.end(); ++it) { a += hash<std::string>(it->first); b += hash<std::string>(it->second); FW_JENKINS_MIX(a, b, c); } m_defineHash = ((U64)b << 32) | c; m_defineHashValid = true; } if (!m_preambleHashValid) { m_preambleHash = hash<std::string>(m_preamble); m_preambleHashValid = true; } U32 a = FW_HASH_MAGIC + m_sourceFileHash; U32 b = FW_HASH_MAGIC + m_optionHash; U32 c = FW_HASH_MAGIC + m_preambleHash; FW_JENKINS_MIX(a, b, c); a += (U32)(m_defineHash >> 32); b += (U32)m_defineHash; FW_JENKINS_MIX(a, b, c); m_memHash = ((U64)b << 32) | c; m_memHashValid = true; return m_memHash; }
bool CudaCompiler::runPreprocessor(std::string& cubinFile, std::string& finalOpts) { // Preprocess. finalOpts = ""; if (s_staticOptions.length()) { finalOpts += s_staticOptions + " "; } finalOpts += m_options; std::string logFile = m_cachePath + "/preprocess.log"; std::string cmd = s_nvccCommand + " -E -o \"" + m_cachePath + "/preprocessed.cu\" " + "-include \"" + m_cachePath + "/defines.inl\" " + finalOpts + " \"" + m_sourceFile + "\" 2>>\"" + logFile + "\""; initLogFile( logFile, cmd); if (0 != system(cmd.c_str())) { setLoggedError("CudaCompiler: Preprocessing failed!", logFile); return false; } // Specify binary format. if (s_staticBinaryFormat.length()) { finalOpts += s_staticBinaryFormat; } else { finalOpts += "-cubin"; } finalOpts += " "; U32 hashA = FW_HASH_MAGIC; U32 hashB = FW_HASH_MAGIC; U32 hashC = FW_HASH_MAGIC; // Override SM architecture. S32 smArch = m_overriddenSMArch; if (!smArch) { smArch = CudaModule::getComputeCapability(); } finalOpts = removeOption(finalOpts, "-arch", true); finalOpts = removeOption(finalOpts, "--gpu-architecture", true); char smArch_str[32]; sprintf(smArch_str, "-arch sm_%d ", smArch); finalOpts += std::string(smArch_str); // Override pointer width. // CUDA 3.2 => requires -m32 for x86 build and -m64 for x64 build. if (CudaModule::getDriverVersion() >= 32) { finalOpts = removeOption(finalOpts, "-m32", false); finalOpts = removeOption(finalOpts, "-m64", false); finalOpts = removeOption(finalOpts, "--machine", true); #if FW_64 finalOpts += "-m64 "; #else finalOpts += "-m32 "; #endif } // Hash final compiler options and version. hashA += hash<std::string>(finalOpts); hashB += s_nvccVersionHash; FW_JENKINS_MIX(hashA, hashB, hashC); // File's timestamp hash to recompile when modified. U64 hashD = getFileTimeStamp( m_sourceFile ); std::string fileName = hashToString(hashB) + hashToString(hashC) + hashToString(hashD); cubinFile = m_cachePath + "/" + fileName + ".cubin"; return true; }
inline U32 hashBits (U32 a, U32 b, U32 c, U32 d, U32 e = 0, U32 f = 0) { c += FW_HASH_MAGIC; FW_JENKINS_MIX(a, b, c); a += d; b += e; c += f; FW_JENKINS_MIX(a, b, c); return c; }
inline U32 hashBits (U32 a, U32 b = FW_HASH_MAGIC, U32 c = 0) { c += FW_HASH_MAGIC; FW_JENKINS_MIX(a, b, c); return c; }