読者です 読者をやめる 読者になる 読者になる

Cucco’s Compute Hack

コンピュータ関係の記事を書いていきます。

DBに特定のデータがあるかどうかを確認する

DB内にデータがあるかどうか確認する。
あった時は更新(update)、なかった時は挿入(insert)するように処理すればよい。

cur.execute(sql,data)に渡した時にSQL文がうまく展開されない?問題で困った。

# -*- coding: utf-8

import mysql.connector
import datetime

config = {
    'user': 'root',
    'password': 'password',
    'host': 'localhost',
    'database':'testdb',
    'charset':'utf8'
}
cnx = mysql.connector.connect(**config)
cur = cnx.cursor(buffered=True)

#tableの削除と作成
sql = 'DROP TABLE IF EXISTS TEST_UPDATE;'
cur.execute(sql)
cnx.commit()
sql = 'CREATE TABLE IF NOT EXISTS TEST_UPDATE (\
							id INT UNSIGNED NOT NULL AUTO_INCREMENT,\
							time DATETIME DEFAULT NULL, \
							value1 INT UNSIGNED DEFAULT NULL ,\
							value2 INT UNSIGNED DEFAULT NULL ,\
							primary key(id),\
							unique (time));'
cur.execute(sql)
cnx.commit()

#初期データのインサート
sql = 'INSERT INTO TEST_UPDATE (time, value1,value2) VALUES (%s, %s, %s);'
data= ('2017-5-01T05:50:00','1','1')
cur.execute(sql, data)

sql = 'INSERT INTO TEST_UPDATE (time, value1,value2) VALUES (%s, %s, %s);'
data= ('2017-5-01T05:50:05','2','2')
cur.execute(sql, data)
cnx.commit()

#この時点でのテーブルの中身
#mysql> select * from test_update;
#+----+---------------------+--------+--------+
#’ id | time                | value1 | value2 |
#+----+---------------------+--------+--------+
#|  1 | 2017-05-01 05:50:00 |      1 |      1 |
#|  2 | 2017-05-01 05:50:05 |      2 |      2 |
#+----+---------------------+--------+--------+
#2 rows in set (0.00 sec)

#データの有無の確認1
sql= "select exists(select * from test_update where time=%s);"
#data=(datetime.datetime(2017,5,1,5,50,00),)
data= ('2017-5-01T05:50:00',)#なぜかカンマが必要。
try:
	cur.execute(sql,data)
except mysql.connector.Error as err:
	print(cur.statement)#実行したSQL文の確認
	raise

#print(cur.fetchone())
#あった時…(1,)
#なかった時…(0,)
if cur.fetchone()[0]==0:
	print("なかった")
else:
	print("あった")

#データの有無の確認2
#テーブル名をdataで渡そうとすると、クォートがついてしまってうまく動かない。
tablename='test_update'
sql= "select exists(select * from " + tablename +" where time=%s);"
data= ('2017-5-01T05:50:05',)
try:
	cur.execute(sql,data)
except mysql.connector.Error as err:
	print(cur.statement)#実行したSQL文の確認
	raise

if cur.fetchone()[0]==0:
	print("なかった")
else:
	print("あった")

#データの有無の確認3
tablename='test_update'
sql= "select exists(select * from " + tablename +" where time=%s);"
data= ('2017-5-01T05:50:15',)
try:
	cur.execute(sql,data)
except mysql.connector.Error as err:
	print(cur.statement)#実行したSQL文の確認
	raise

if cur.fetchone()[0]==0:
	print("なかった")
else:
	print("あった")

cur.close()
cnx.close()
print('end')

pythonのunittestのコード

ちょっと前に書いた記事compute-cucco.hatenablog.comのテストコード。というか抽象クラスは関係ないので、ただのテストコード。
raiseに対するテストコードの書き方が分からない。。。

# -*- coding: utf-8 -*-
import unittest
import movingCalcs
from movingCalcs import factory

class TestmovingCalcs(unittest.TestCase):
	"""test class of movingCalcs.py
	"""

	def test_add(self):
		"""test method for Add
		"""
		node = factory("Add")
		value1 = 1
		value2 = 2
		expected = 3
		actual = node.calc(value1, value2)
		self.assertEqual(expected, actual)

	def test_sub(self):
		"""test method for sub
		"""
		node = factory("Sub")
		value1 = 1
		value2 = 2
		expected = -1
		actual = node.calc(value1, value2)
		self.assertEqual(expected, actual)

	def test_zero(self):
		"""test method for Zero
		"""
		node = factory("Zero")
		value1 = 1
		value2 = 2
		expected = 0
		actual = node.calc(value1, value2)
		self.assertEqual(expected, actual)

	def test_other(self):
		"""test method for other
		"""
		with self.assertRaises(factory):
			node = factory("Other")

if __name__ == "__main__":
    unittest.main()

Jenkinsのインストール(CentOS on raspberry pi3)

インストール手順は以下にアリ。
RedHat Repository for Jenkins

追記:Javaがない、といってJenkinsの起動に失敗します。動作確認はまた後日。

# sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo: wget: コマンドが見つかりません

wgetがない、と言われたので以下に書き換え。

sudo curl -o /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo

中身を確認すると。

# more /etc/yum.repos.d/jenkins.repo
[jenkins]
name=Jenkins-stable
baseurl=http://pkg.jenkins.io/redhat-stable
gpgcheck=1

後は指示通り。まとめると以下。

sudo curl -o /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install jenkins

Raspberry Pi3にCentOS

CentOSが入るらしいのでやってみた。
wi-fiのドライバを別途ダウンロードする必要があるので、Raspberry Pi3に有線LANが必要。

ダウンロード

Download CentOS

More download choicesへ。
http://wiki.centos.org/Download

AltArch Releasesの中に、RaspberryPi3 (img)があるのでこれを使う。
f:id:Cucco:20170423163112p:plain

http://mirror.centos.org/altarch/7/isos/armhfp/CentOS-Userland-7-armv7hl-Minimal-1611-RaspberryPi3.img.xz

上記を解凍して(7zipなど)、イメージ書き込みツールでSDカードに書き込み。ここはraspbianと同じ。

ログイン

ログインID、パスワードはroot/centos。ここに書いてある。
https://wiki.centos.org/SpecialInterestGroup/AltArch/Arm32/RaspberryPi3

rootのパスワードの変更
#passwd

ディスクの拡張

ディスクの拡張は以下。/root/READMEに書いてある。

If you want to automatically resize your / partition, just type the following (as root user):
/usr/local/bin/rootfs-expand

Wifiの認識

Wifiの認識は以下。ファイルを落として再起動。これをやってもwifiのアダプタを認識するだけなので、設定は別。

For wifi on the rpi3, just proceed with those steps :

curl --location https://github.com/RPi-Distro/firmware-nonfree/raw/master/brcm80211/brcm/brcmfmac43430-sdio.bin > /usr/lib/firmware/brcm/brcmfmac43430-sdio.bin

curl --location https://github.com/RPi-Distro/firmware-nonfree/raw/master/brcm80
211/brcm/brcmfmac43430-sdio.txt > /usr/lib/firmware/brcm/brcmfmac43430-sdio.txt

systemctl reboot

Wifiの設定(raspberry Pi3にcentos7を入れてみた - Qiitaより)

[root@centos-rpi3 ~]# nmcli d
バイス タイプ 状態 接続
eth0 ethernet 接続済み eth0
wlan0 wifi 管理無し --
lo loopback 管理無し --

$ nmcli d wifi
# -> Wifiアクセスポイントのリストが一覧されます
$ nmcli d wifi connect password

キーボードの設定(raspberry Pi3にcentos7を入れてみた - Qiitaより)

centos
$ localectl set-keymap jp106
$ localectl set-keymap jp-OADG109A

##System Localeを変更もしておきます
$ localectl set-locale LANG=ja_JP.utf8

##localectlで確認
$ localectl
System Locale: LANG=ja_JP.utf8
VC Keymap: jp-OADG109A
X11 Layout: jp
X11 Model: jp106
X11 Options: terminate:ctrl_alt_bksp

Abstract Base Classのテスト

Abstract Base Classのテスト。
メソッド名が同じで、引数が異なるオブジェクトの生成と実行のサンプルです。
メソッド名を共通で固定したいので、Abstract Base Classを使ってみました。

変数名にnameを使っていたら、「TypeError: 'str' object is not callable」と怒られたのでclassNameとしています。

# -*- coding: utf-8 -*-
from abc import ABCMeta, abstractmethod

# 抽象クラス
class CalcNode(metaclass=ABCMeta):
	@abstractmethod
	def className(self):
		pass
	
	@abstractmethod
	def calc(self):
		pass

#抽象クラスの中身。Zero,Add,Subの3つのクラス
class classZero(CalcNode):
	def __init__(self):
		self.name = "Zero"
	
	def className(self):
		return self.name
	
	def calc(self,val1=1,val2=2):
		return 0

class classAdd(CalcNode):
	def __init__(self):
		self.name= "Add"
	
	def className(self):
		return self.name
	
	def calc(self,val1=1,val2=2):
		return val1+val2

class classSub(CalcNode):
	def __init__(self):
		self.name= "Sub"
	
	def className(self):
		return self.name
	
	def calc(self,val1=1,val2=2):
		return val1-val2

def factory(className):
	if className=="Zero":
		return classZero()
	elif className=="Add":
		return classAdd()
	elif className=="Sub":
		return classSub()
	else:
		raise

def main():
	nodes=(factory("Add"),
			factory("Zero"),
			factory("Sub"))
	
	for node in nodes:
		print(node.className())
		print(node.calc(val1=2,val2=5))
		print(node.calc(val2=5,val1=2)) #入れ替えても大丈夫
		print(node.calc(2,5))           #変数名を省いても大丈夫
		print(node.calc(val1=100))      #片方だけ入れても大丈夫
		print(node.calc(val2=100))      #片方だけ入れても大丈夫
		print(node.calc())              #何も入れなくても大丈夫

#main()を実行する
if __name__== '__main__':
    main()

Failed to create session. CUDA_ERROR_INVALID_DEVICE

古いGPUがついていると、こんなエラーになることがある。

$cd /usr/local/lib/python3.5/dist-packages/tensorflow/models/image/mnist
$/usr/local/lib/python3.5/dist-packages/tensorflow/models/image/mnist$ python3 convolutional.py
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcublas.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcudnn.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcufft.so locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcuda.so.1 locally
I tensorflow/stream_executor/dso_loader.cc:128] successfully opened CUDA library libcurand.so locally
Extracting data/train-images-idx3-ubyte.gz
Extracting data/train-labels-idx1-ubyte.gz
Extracting data/t10k-images-idx3-ubyte.gz
Extracting data/t10k-labels-idx1-ubyte.gz
I tensorflow/stream_executor/cuda/cuda_gpu_executor.cc:937] successful NUMA node read from SysFS had negative value (-1), but there must be at least one NUMA node, so returning NUMA node zero
I tensorflow/core/common_runtime/gpu/gpu_device.cc:885] Found device 0 with properties:
name: GeForce GTX 1070
major: 6 minor: 1 memoryClockRate (GHz) 1.7465
pciBusID 0000:01:00.0
Total memory: 7.92GiB
Free memory: 7.79GiB
W tensorflow/stream_executor/cuda/cuda_driver.cc:590] creating context when one is currently active; existing: 0x314aa00
E tensorflow/core/common_runtime/direct_session.cc:135] Internal: failed initializing StreamExecutor for CUDA device ordinal 1: Internal: failed call to cuDevicePrimaryCtxRetain: CUDA_ERROR_INVALID_DEVICE
Traceback (most recent call last):
  File "convolutional.py", line 339, in <module>
    tf.app.run(main=main, argv=[sys.argv[0]] + unparsed)
  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/platform/app.py", line 43, in run
    sys.exit(main(sys.argv[:1] + flags_passthrough))
  File "convolutional.py", line 284, in main
    with tf.Session() as sess:
  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/client/session.py", line 1186, in __init__
    super(Session, self).__init__(target, graph, config=config)
  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/client/session.py", line 551, in __init__
    self._session = tf_session.TF_NewDeprecatedSession(opts, status)
  File "/usr/lib/python3.5/contextlib.py", line 66, in __exit__
    next(self.gen)
  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/framework/errors_impl.py", line 469, in raise_exception_on_not_ok_status
    pywrap_tensorflow.TF_GetCode(status))
tensorflow.python.framework.errors_impl.InternalError: Failed to create session.
 

こうやって実行すれば、GPUを0だけ使用して、実行する。

$CUDA_VISIBLE_DEVICES=0 python3 convolutional.py

以下でも可。

$export CUDA_VISIBLE_DEVICES=0
$python3 convolutional.py

以下の定数も必要な様子。

export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64"
export CUDA_HOME=/usr/local/cuda

CUCA Toolkitのインストール (network deb)

Ubuntu 16.04にCUCA Toolkitのインストールした時のメモ。
CUDA ToolkitCUDA 8.0 Downloads https://developer.nvidia.com/cuda-downloads

Select Target Platformから
Operating System:Linux
Architecture:x86_64
Distribution:Ubuntu
Version:16.04

Installer Typeで、[deb (network)]を選ぶと、
実行手順として以下を実行しろ、と言われる。
cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb自体は、wgetでローカルに保存しておく。

wget http://developer.download.nvidia.com/compute/cuda/repos/ubuntu1604/x86_64/cuda-repo-ubuntu1604_8.0.61-1_amd64.deb
Installation Instructions:
1. sudo dpkg -i cuda-repo-ubuntu1604-8-0-local-ga2_8.0.61-1_amd64.deb
2. sudo apt-get update
3. sudo apt-get install cuda