VS2015下CUDA代码编译异常的一点小问题解决方法

安装了 VS2015后,下载了CUDA 8.0安装,试了一个.cu文件编译正常通过,
继续安装了一个Intel parallel_studio_xe_2016, 然后使用 Intel 的C++编译器进行编译,结果nvcc编译.cu文件时候报错,一些c++库的头文件解析不通过,
网上搜索了一下,没有找到解决方法。

自己对比了一下使用VS 的C++编译器和 Intel 的C++编译器时,在控制台输出的nvcc命令,发现 –cl-version 参数值不同

使用VS2015的C++编译器时,出现的参数是 –cl-version 2015
而使用Intel的C++编译器时,出现的参数是 –cl-version 2010

进一步查找CUDA的自定义编译配置,在 Program Files(x86)\MSBuild\Microsoft.Cpp\v4.0\v140\BuildCustomizations\ 目录下的 CUDA 8.0.props 中对编译器做了检查,

...
<CudaClVerson Condition="'$(PlatformToolset)' == 'v140'">2015</CudaClVersion>
<CudaClVersion Condition="'$(CudaClVersion)' == ''">2010</CudaClVersion>
...

CUDA的自定义编译配置中没有对Intel C++编译器做判断处理,自己修改下面那个为空时默认为2010的行,
将2010修改为2015,保存后重新编译,两个编译器都可以编译通过,问题解决。

Popularity: 1% [?]

Random Posts

在CentOS 6 下安装TensorFlow

在CentOS下安装TensorFlow的一些步骤
首先按照TensorFlow官方安装教程,选择了anaconda 环境, 下载安装了 anaconda3 环境后(为python3.6),
在里面按照官方步骤使用pip方式安装tensorflow包, 安装后在python中 import tensorflow as tf 出错,提示缺少LIBC_2.17之类的符号,这是由于CentOS自带版本比较低的缘故,需要源码编译方式进行安装。
安装TensorFlow需要使用支持c++11版本的编译器,CentOS 6自带的g++ 4.4.7不支持,首先需要安装一个版本的g++, 我选择了安装4.9.4版本
步骤1. 安装gcc 4.9.4

tar -xjvf  gcc-4.9.4.tar.bz2
cd gcc-4.9.4
./contrib/download_prerequisites
./configure --prefix=/opt/gcc/4.9.4  --languages=c,c++ --disable-multilib
make
make install

安装好后,设置环境变量,在 ~/.bashrc 中添加如下内容

export CXX=/opt/gcc/4.9.4/bin/c++
export CC=/opt/gcc/4.9.4/bin/gcc
export LDFLAGS="-L/opt/gcc/4.9.4/lib -L/opt/gcc/4.9.4/lib64"
export CXXFLAGS="-L/opt/gcc/4.9.4/lib -L/opt/gcc/4.9.4/lib64"
export C_INCLUDE_PATH=/opt/gcc/4.9.4/include
export CXX_INCLUDE_PATH=$C_INCLUDE_PATH
export LD_RUN_PATH=/opt/gcc/4.9.4/lib/:/opt/gcc/4.9.4/lib64/
export LD_LIBRARY_PATH=/opt/gcc/4.9.4/lib/:/opt/gcc/4.9.4/lib64/

重新开启一个终端窗口,下载源码安装 bazel

mkdir bazel
cd bazel
unzip ~/Downloads/bazel-0.4.5-dist.zip
./compile.sh

编译完成后得到一个 bazel执行文件,拷贝到/usr/local/bin 目录下,
对这个生成的bazel文件不能使用strip,否则后面使用时会出现zip资源释放出错的消息

下载安装tensorflow, 到github上下载1.1分支包

unzip tensorflow-r1.1.zip
cd tensorflow-r1.1
./configure
#按照提示做一些选择
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
#这一步在build过程中碰到执行protoc命令出错的问题,提示找不到LIBCXX之类的符号信息,设置的LD_LIBRARY_PATH值没有起作用
#解决方法,将~/.bashrc中LD_LIBRARY_PATH=/opt/gcc/4.9.4/lib/:/opt/gcc/4.9.4/lib64/路径添加到/etc/ld.so.conf中去就可以通过了
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg

最后重新按照官方教程进入anaconda3环境

source activate tensorflow
pip install --ignore-installed --upgrade /tmp/tensorflow_pkg/tensorflow-1.1.0-cp36-cp36m-linux_x86_64.whl

进入python3做测试,在 import tensorflow as tf 时出错,
提示 anaconda3/lib/python3.6/site-packages/tensorflow/python/_pywrap_tensorflow_internal.so 缺少一个 CXXABI_1.3.7的错误,
ldd查看了一下,依赖的是libstdc++.so.6是指向anaconda3/lib/libstdc++.so.6.0.19,而不是编译的gcc-4.9.4目录下的libstdc++.so.6.0.20
重新建立anaconda3/lib目录下的符号连接指向/opt/gcc/4.9.4/lib64/libstdc++.so.6.0.20
(估计使用gcc-4.8.5编译tensorflow就不会有这个问题了,生成的库同是libstdc++.so.6.0.19)

再次进入python3做测试,通过没有问题,将~/.bashrc 和 /etc/ld.so.conf中的关于gcc 4.9.4路径设置的环境变量去掉,测试tensorflow还是正常

Popularity: 1% [?]

Random Posts

MindManager2017配套插件ResultManager和MindReader使用注意点

换回Windows系统使用,安装上了MindManager 2017, 同时也找回很久以前的两个配套插件
ResultManager www.gryonix.com 新的MindManager 2017版本插件已经转移到 www.olympic-limited.co.uk 公司开发维护。
MindReader http://wiki.activityowner.com/index.php?title=MindReader

安装MindReader 要注意几个要点,否则使用会有异常
1. 安装时,虽然安装包有让修改安装路径,但是千万不能能修改,安装在非默认路径下插件运行会出错
2. 在MindManager安装后的MyMaps目录下要有如下两个文件

3. 初次通过MindReader建立主题,会提示创建/升级配置文件,配置文件路径在 MyMaps目录下的 ao\mindreaderconfig.mmap 中
在MindManager中打开这个配置文件,
a. 修改 links->defaultmap的路径,使其指向 MyMaps\Daily Capture Map.mmap,
如果不设置,则每次通过MindReader创建主题都会新建一个脑图文件。
b. 修改 CustomIcons 中 rmproject 和 rmresult 的图标基准路径为 C:\Program Files (x86)\Gyronix\Gyronix ResultsManager v3 for MindManager 2017 x86\Images 可以根据实际安装的路径做修改。
c. 其他根据自己需要添加修改的配置项

Popularity: 1% [?]

Random Posts

MySQL Connector++ 使用getString获取表字段数据出错

Linux下一个使用MySQL Connector++ 1.1.0 连接MySQL数据库的程序,在连接数据库获取数据时程序崩溃,
确定数据库中存在记录值,查看Core Dump文件,发现崩溃点发生在调用 MySQL 库的 getString 方法时的那一行,

通过google搜索,发现好一些getString出错的问题,但是多数是Windows下VS编译环境不同造成的,终于发现下面一篇中有和我的问题类似

http://stackoverflow.com/questions/4822958/mysql-c-connector-getstring-doesnt-work-correctly-while-getint-works-perfe

I had a similar problem the program would give a memory exception. Here is what I did to fix it:
std::string version = result->getString( COLUMN_NAME ).c_str();

This didn't work:
sql::SQLString sString  = result->getString( COLUMN_NAME ); <<

我的不正常代码是

std::string value = result->getString( field);

按照上面的方法将代码修改为

std::string value = result->getString( field).c_str();

暂时获取同样的数据没有出错,希望后面也不要出错。
MySQL Connector++ 从版本1.1.4开始编译依赖于BOOST库

Popularity: 1% [?]

Random Posts

    libevent2的evhttp获取网页数据失败(dns未能正确解析)

    使用libevent2的evhttp请求阿里大于接口,调用失败,没有正确请求数据,但是利用curl可以正确访问。
    使用抓包工具抓包分析,和curl发起的请求对比发现libevent2在dns查询后没有连接实际的ip地址建立连接,怀疑libevent2没有正确的对dns解析结果做处理。
    网上搜索发现如下这篇文章:域名随机大小写导致libevent2的异步DNS解析失败

    经过检验,确实时dns查询阿里大于api接口域名返回的应答信息中,域名大小写和请求时的有所不同,
    于是翻看libevent2的代码,发现有函数evdns_base_set_option可以设置global_randomize_case的值,

    在阿里大于接口请求前添加一样代码:
    evdns_base_set_option(dnsbase, “randomize-case”, “0″);
    重新编译运行,解决问题。

    Popularity: 2% [?]

    Random Posts

      Linux下df和du看到的剩余空间不一致处理方式

      昨日突然测试用的Linux服务器报存储空间不足,使用 df 查看,磁盘已经使用 100%,使用du 命令查看使用空间最大的目录,结果发现 du 显示的总使用空间才占用总磁盘空间的 70%左右,剩下的 30%空间跑哪去了呢?
      找了一下df和du区别的资料,发现他们的工作方式有所区别,所以造成了看到的结果不一致

      du的工作原理
      du命令会对待统计目录下的文件逐个调用fstat,获取每个文件大小。它的数据获取是基于文件目录中的文件的,可以跨越多个分区操作。如果目录中文件很多,那么du的速度就会很慢.

      df的工作原理
      df命令使用statfs这个系统调用,直接读取分区的超级块信息获取分区使用情况。它只能针对整个分区块,运行速度不受文件多少的影响。

      du和df不一致的一般原因
      常见的df和du不一致情况是文件删除造成的,当一个文件被删除后,在文件系统目录中已经不可见了,所以du就不会再统计它了。然而如果这个时候还有运行的进程持有这个已被删除了的文件的句柄,那么这个文件就不会真正在磁盘中被删除,分区超级块中的信息也就不会更改。这样df仍旧会统计这个被删除了的文件。

      一般处理方法
      使用lsof命令找到还持有被删除文件句柄的进程,然后关闭进程或者杀掉进程用以释放空间。

      lsof | grep deleted

      避免这个问题的一般方法
      1.可以使用清空文件的方式来代替删除文件,方式是:

      echo > myfile

      2.对于要经常做删除操作的日志文件,以改名、清空、删除的顺序操作

      Popularity: 2% [?]

      Random Posts

        NDK回调Java类方法碰到的问题解决

        以前写的一个Android程序,使用NDK回调Java中的类函数方法,以前在Android 4.x之前的系统上都没有问题,5.x,6.x系统的手机上在回调Java类函数时,出错,报:… invalid object …

        搜索Google发现,是由于jni接口触发时,传入的jobject对象使用的是Local reference方式,而自己写的ndk代码是将这个类对象存起来作为全局对象使用了。

        http://android-developers.blogspot.com/2011/11/jni-local-reference-changes-in-ics.html

        JNI 函数参数中 jobject 或者它的子类,其参数都是 local reference。Local reference 只在这个 JNI函数中有效,JNI函数返回后,引用的对象就被释放,它的生命周期就结束了。若要留着日后使用,则需根据这个 local reference 创建 global reference。Global reference 不会被系统自动释放,它仅当被程序明确调用 DeleteGlobalReference 时才被回收。(JNI多线程机制)
        gobj=(*evn)->NewGlobalRef(evn, object);

        需要在存起来的地方将这个类对象先NewGlobleRef一下,使其不会由于在退出这个保存对象的jni调用后就因为Local临时对象引用被销毁掉,导致后续的NDK调用访问不到这个临时对象,报错跳出程序。

        代码做了这个小修改后,再在NDK代码中调用这个java类的方法,程序没有再报错。

        Popularity: 2% [?]

        Random Posts

          尝试安装使用Checkmarx过程中碰到的问题解决方法记录

          最近找到了一份Checkmarx安装包,这是一款比较强大的用于静态分析源代码,找出代码中可能存在的安全漏洞,
          对常见的语言都有支持,比如ASP,PHP,Rubby,Python,JavaScript,CSharp,Java等

          在尝试安装使用的过程中碰到了如下一些问题:

          1. 使用的SQLServer数据库连接不上
          2. 开始默认安装的系统认证方式连接数据库,结果启动服务时起不来,看日志为数据库连接不上,提示NT Authrity失败,于是尝试使用SQLServer的认证,修改Config目录下的数据库连接配置文件,添加上User Id,Password数据库连接账号,重新启动Checkmarx的服务,发现还是连不上,查看SQL Server的文档,发现Integrated Security要设置为False值,否则还是会忽略数据库的账号密码,使用系统认证连接数据库。再次修改后,重新启动服务,启动成功。

          3. Git版本库连接不上
          4. 添加要扫描的项目代码时,使用Git版本库作为来源,但是总是提示ssh认证不通过,最后发现使用git2.x的客户端不行,网上找了一个git1.9的客户端在Checkmarx的扫描服务器上重新安装,问题解决。

          5. 使用中文界面,部分漏洞的中文说明显示为乱码
          6. 分析显示的文字,感觉是没有正确采用编码显示,感觉像utf-8编码未能正常显示,在数据库服务器上打开CxDB数据库,找到cwe表,看到里面有LanguageId为2052的Description字段中文字有中文,抽样看了一些字段中数据值,部分正常显示中文,部分显示出来为乱码。写了一个小工具,对显示不正常的记录数据读取出啦,转为Utf8编码重新保存到数据库中(一共200多条中文描述记录中有90来条乱码),Web页面上原先显示不正常的中文显示正常。但是生成的中文报告,原先乱码的在报告中还是乱码,应该需要修订另外一个字段中的值。

          Popularity: 2% [?]

          Random Posts

            JIRA和HipChat服务端集成时,提示不能访问HipChat服务器地址问题的解决

            HipChat现在可以安装在本地环境,试着装了一个,在网上申请了免费SSL证书设置后,浏览器打开没有提示非安全站点的问题,一切正常。
            然后尝试将HipChat和Jira集成,
            通过Market市场在Jira上下载安装了HipChat的插件,安装后,在Jira后台管理界面系统那页Email配置项目下面出现了HipChat集成设置菜单项,
            输入安装的HipChat服务器地址, https://mychat.mydomain.com, 点击确定,提示不能连接HipChat服务地址,浏览器中打开地址确是正常的。
            想不通问题,查看jira的日志文件,发现有日志

            javax.net.ssl.SSLHandshakeException: sun.security.validateor.ValidatorException:
              PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException:
                unable to find valid certification path to requested target
            

            原来是SSL证书问题,因为不是默认可以被java认可的根证书签名,需要导入证书。

            keytool -import  -alias mycert -file root.crt -keystore $JAVA_HOME/jre/lib/security/cacerts
            

            输入密码 changeit,导入证书
            使用如上命令导入申请的免费SSL证书的crt证书文件后,再次设置HipChat服务器地址,确认,顺利进入集成设置界面。

            Popularity: 2% [?]

            Random Posts

              SOATest浅尝使用脚本设置HTTP请求参数

              SOATest是Parasoft公司的一款测试工具,功能强大,可以用于Http接口测试。通常指定好接口地址,设置好输入参数列表后,即可获得接口数据做检查。
              碰到一个http请求要做参数签名的情况,请求需要添加两个参数,
              _timestamp 请求发生时的Unixtime 时间戳
              _sign 对所有参数值排序后连接起来,和一个协商好的 secret 值做md5运算 _sign=md5(secret + 排序后的参数值字符串 + secret)

              这两个参数不能在输入时确定,需要在发生请求是动态生成,因此需要写脚本来设置。
              翻看了SOAtest的用户手册 和 SOAtest Extensibility API帮助文档,没有找到获取请求参数列表的方法,
              经过多番研究尝试,最终搞定,脚本如下

              脚本1. 获取时间戳值

              from java.util import *
              from java.text import *
              from java.lang import *
              
              def getTime():
                calendar = Calendar.getInstance()
              
                date = calendar.getTime()
              
                ts = date.getTime() / 1000
                return ts
              

              脚本2. 获取参数列表后,对参数列表做签名计算

              from com.parasoft.api import *
              from webtool.data import *
              from java.lang import *
              from java.util import HashMap
              from java.security import *
              
              #计算参数签名
              def getParamsSign(context):
                  mc = context.getTool()
                  params = mc.getURLParams()
                  names = []
                  mp = HashMap()
                  for p in params:
                      name = p.getName()
                      if name != "_sign":
                          value = p.getValue(context)
                          mp.put(name,value)  # 将需要签名的参数放到列表中存起来
                          names += [name]
                          #Application.showMessage('param ' + name + ' value '+ value)
                      else:
                          #Application.showMessage('param _sign value ' + p.getActualValue())  #不能调用p.getValue(context), 会触发死循环  
              
                  #拼装要签名的字符串
                  names.sort()
                  tosign = ''
                  for k in names: #mp.keySet():
                      tosign += k;
                      tosign += mp.get(k)
                  secret = context.getEnvironmentVariableValue('client_secret')
                  tosign = secret + tosign + secret
                  Application.showMessage('tosign:' + tosign)
              
                  #作签名运算
                  md5Inst = MessageDigest.getInstance('MD5')
                  md5Inst.update(tosign.encode('utf-8'))
                  hexDigits = '0123456789abcdef'
                  md = md5Inst.digest()
                  signed = ''
                  for v in md:
                      t = v >> 4 & 0x0f
                      signed += hexDigits[t]
                      t = v & 0x0f
                      signed += hexDigits[t]
                  Application.showMessage('signed:' + signed)
                  #返回签名结果
                  return signed
              

              注意要点,在获取参数列表时,用于参数签名的 _sign 字段名要刨除在外,否则获取_sign值时会触发脚本,陷入死循环

              Popularity: 2% [?]

              Random Posts

                Next Page →