スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

pyCUDAをUbuntu 14.04 + CUDA 6.5で使う

以前の記事のアップデートである。

CUDA 6.5はNVIDIA側でUbuntu 14.04に対応しているので、インストールには特別なことは必要ない。
ただし以前のバージョンのcuda、nvidia関連のパッケージは

dpkg -l | grep nvidia
dpkg -l | grep cuda

で調べた上で、一旦アンインストールしておくのがいいだろう。

その上で、NVIDAのダウンロードサイトからcuda-repo-ubuntu1404_6.5-14_amd64.debを持ってきてgdebi等でインストールする。

そして

sudo apt-get update
sudo apt-get install cuda

を実行すればインストールは完了する。約1.7GBほどのディスク領域を使用する。

ここまでで、CUDA 6.5を直接利用するのには問題ない。

一方、pyCUDA等の、CUDAを内部で使用するUbuntuでパッケージングされているソフトウェアは、CUDAのUbuntuでパッケージとして用意されているバージョンである5.5に対してリンクされているのでこのままではインストールできない。無理にインストールするとCUDA 5.5も一緒にインストールされてしまい、CUDA 6.5の環境が破壊される。

そこでCUDA5.5相当の機能がすでにインストールされていることをパッケージデータベースに登録するためのフェイクパッケージを作成する。フェイクパッケージは、2つ必要である。

最初のパッケージは、名前は何でもよいのだが、mycudaglueとする。
次のようなテキストファイルを作成する。(SourceとMaintainerは適宜変更)

### Commented entries have reasonable defaults.
### Uncomment to edit them.
# Source:
Section: misc
Priority: extra
Homepage: http://gm3d.blog.fc2.com
Standards-Version: 3.9.2

Package: mycudaglue
Version: 6.5-14
Maintainer: GM3D (@gm3d2 on twitter)
#Depends: cuda (>= 6.5)
Provides: libcublas5.5, libcudart5.5, libcufft5.5, libcufftw5.5,
libcuinj64-5.5, libcurand5.5, libcusparse5.5, libnppc5.5,
libnppi5.5, libnpps5.5, libnvtoolsext1, libnvvm2,
libthrust-dev, libvdpau-dev, nvidia-cuda-dev, nvidia-cuda-doc,
nvidia-cuda-gdb, nvidia-cuda-toolkit, nvidia-libopencl1-331,
nvidia-opencl-dev, nvidia-profiler, nvidia-visual-profiler,
opencl-headers

このファイルをmycudaglueという名前でセーブして、
equivs-build mycudaglue
でできたパッケージをgdebiでインストール。

もう一つはlibcurand5.5のフェイクパッケージである。

libcurand5.5という名前で、以下のファイルを作成。

Section: misc
Priority: optional
Standards-Version: 3.9.2

Package: libcurand5.5
Version: 99
Maintainer: GM3D (@gm3d2 on twitter)

このファイルから、
equivs-build libcurand5.5

によりパッケージを生成、インストールする。これでpyCUDAに関しては依存性が満たされるはずである。念のため、一回

sudo aptitude -s install python-pycuda

でシミュレートを行い、インストールされるのがpython-pycuda、python-pycuda-docのみであることを確認した後、

sudo aptitude install python-pycuda

でインストールを行えば良い。

テストは、上記エントリにも書いてあるように、pyCUDAのhello_gpu.pyあたりを実行してみればよい。
スポンサーサイト

Google calendar APIをPythonスクリプトから使う

最近になってだんだんGoogleカレンダーで予定の管理をする頻度が増えてきたのだが、定型的なスケジュールを先まで登録するのにいちいちWebインターフェースで開始時間と登録時間やその他の項目を設定するのが面倒になってきた。

まったく同一内容で、同じ時間帯に繰り返されるようなスケジュールなら、繰り返しのパラメータを指定すればよい。だがここでは、学校の時間割のように、時間枠は毎日一定だが中身は順繰りに変わる、といったような形式のものを考える。

30分くらい思考停止してブラウザ上で黙々とクリックして登録しまくれば一月分くらいすぐ登録できそうであるが、それよりは一日頭をひねってAPIの使い方を習得した方が、自分としては心理的ストレスは少ない。

Google Calendar API自体はREST形式のHTTPリクエストをベースにしているので、まず認証から実際にカレンダーを操作するまでの流れ自体を、

Google Apps Calendar APIの使い方(カレンダーに予定を登録してみる) - howdylikes:

にしたがって、一度ブラウザベースで実行し、感触をつかむことをおすすめする。

その上で、ここではPythonベースで、コマンドラインインターフェースからの操作を行うことが目的である。
基本的な流れとしては、スクリプトの作成前に、先にこれから作成するスクリプトを、Google APIのサーバに対してアプリケーションとして登録して、アプリケーション固有のID(クレデンシャル)を発行してもらう必要がある。あらかじめ登録済みのアプリケーションのみがGoogle APIにアクセスすることを認められるというわけだ。

具体的には、以下のように準備を進めていく。

Google Developers Console
に行き、新規プロジェクトを作成する。そして、作成できたらそのプロジェクトの設定を開き、APIs & auth → APIs の欄で、Calendar APIをONにしておく。スクリーンショットでは上の方に表示されているが、これはONにした後なので、ONにする前はリストの下の方に表示されているので注意してほしい。
google_dev_console1.png

次に、Google API 用のPythonクライアントライブラリをインストールする。
Google APIs Client Library for Python — Google Developers:に行く。
このページの上半分、Runs on Google App Engineまでのところは無視してよい。単に、Client library installationの項にある通り、管理者権限で、

$ sudo pip install --upgrade google-api-python-client

とすれば、クライアント側で必要なPythonライブラリがインストールされる。もちろん、Python(2.x)とpipが使えることが前提である。
そして、そのまま同じページでAPIと環境を選ぶ。ここではCalendar APIと、Python/Command Lineを選択する。そしてConfigure Projectボタンを押す。すると、このアプリケーション用に認証用のクレデンシャルが生成され、次のように画面が遷移する。
google_dev_consosle2.png

そこに書いてある通りに"Download the starter application"からcalendar-python-cmd-line.zipをダウンロードし、適当なディレクトリで解凍し、そこに移動する。また、"Download the client secrets file"からclient_secrets.jsonファイルをダウンロードする。このファイルに、このプロジェクトに属するプログラムを認証してもらうためのクレデンシャルが入っているので、解凍してできたcalendar-cmd-line-sampleディレクトリにある同名のダミーファイルをこれで置き換える。

この時点で、calendar-cmd-line-sampleフォルダ内のsample.pyスクリプトが動作するはずである。このスクリプトは、client_secrets.jsonからクレデンシャルを読み込んで、それを用いてOAuth 2.0認証を行うところまでを実行するようになっている。引数なしで実行してみると、初回だけブラウザが自動的に立ち上がり、このアプリケーションはカレンダーデータへのアクセスを行うことが通知されるので、Acceptを押す。(「誰の」カレンダーかと言えば、最初にアプリケーションを登録するときにGoogleアカウントが必要なので、そのユーザーのカレンダーということになる)
google_api1.png

これでうまく行けば、

Authentication successful.
Success! Now add code here.

というメッセージが表示されて、認証は完了である。なお、ブラウザがインストールされていないなどで自動起動できない環境の場合、--noauth_local_wevserverオプションをつけて実行すると、ブラウザが起動する代わりに、コマンドライン上に認証用のURLと、

"Enter verification code:"

というメッセージが表示される。このURLを別マシンのブラウザなりで開き、そこに表示される認証コードをプロンプトに入力すれば初回認証が完了する。

初回認証さえ完了すれば、後は帰ってきたトークンがsample.datファイル内に保存され、次回以降はこれを使って認証が行われる。

引数なしだと2回目以降もブラウザが起動されるかもしれないが、その場合--noauth_local_wevserverオプションを使用すれば、もう認証コードを要求されることはないので完全にコマンドラインオンリーで操作は完結する。試していないが、グラフィック環境のないマシンであれば、この段階までデスクトップマシンで実行してからディレクトリごとターゲットマシンにコピーすればいいのではないだろうか。

ここまでうまくいけば、後はsample.pyの

try:
print "Success! Now add code here."
except client.AccessTokenRefreshError:
print ("The credentials have been revoked or expired, please re-run"
"the application to re-authorize")

のtry節の部分に具体的なカレンダーAPI操作を付け加えればいいだけである。一通りどんな操作が可能かは最初に紹介したブログなどでつかんでもらったとして、個々の操作を各言語のバインディングでどう行えばいいかは、Google Calendar API - Google Calendar API — Google Developers:
にある。たとえば、予定の作成を行う場合、

try:
events = service.events().insert(calendarId='primary',
body=citem).execute()
except client.AccessTokenRefreshError:
print ("The credentials have been revoked or expired, "
"please re-run the application to re-authorize")

としてやればよい。ここで、citemには、APIで必要な各パラメータを正しい形式で格納したPythonの辞書オブジェクトを指定する(RESTで要求されるJSONではない)。実は最初は、bodyにJSONを指定するとどうしても”Missing end time"というエラーで登録できなかったのだが、どうもPython クライアントライブラリを使う場合、「なんだかJSONを渡さなければならない気がしていたが、よく考えたらそんなことはなかったぜ」ということのようである。

ここまでできたら、後は各自の要求に合わせて処理を拡張することは容易だろう。
私は最初に述べたように、時間枠は固定、中身は一定のリストの中からある規則にしたがって順番に変わっていくような予定を自動的に登録したかったので、最後にそのスクリプトをやや長いがそのまま挙げておく。

具体的には、

py cal3.py 0614 0621 --noauth_local_webserver

のように実行する。第一引数と第二引数で登録開始日と終了日を指定すると、その範囲にわたって学校の時間割にそこはかとなく似たものを自動生成、登録してくれる。年は現在の年固定にしてある。

google_calendar1.png

予定のタイトル(サマリー)一覧はリストではなく辞書にしてあって、あるサマリーの相対的な出現頻度をサマリーをキーとした値として一応持たせてあるが、このバージョンではその情報はまだ利用しておらず、単にキーを順繰りに返すようになっている。

まあ、かなりやっつけ的なスクリプトなのだが、今のところこれ以上凝った自動化の要求が個人的にないのでこうなっている。より洗練されたものにすることは容易だろう。


# -*- coding: utf-8 -*-
# cal3.py
import inspect
import sys
import datetime
import argparse
import httplib2
import os
import string

from apiclient import discovery
from oauth2client import file
from oauth2client import client
from oauth2client import tools

summary_pool = {"量子光学":2, "プログラミング":2, "素粒子論":1, "量子観測理論":2, "マシンラーニング":2, "統計力学":1}

scheduled_times = (("08:00", "09:45"),
("10:00", "11:45"),
("12:45", "14:30"),
("14:45", "16:30"),
("16:45", "18:30"))

def pick(pool):
i = 0
l = len(pool)
while True:
for key, val in pool.items():
yield key

def main(argv):
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
parents=[tools.argparser])
argc = len(argv)
flags = []
print argc, argv
if argc >= 3:
start_date = argv[1]
end_date = argv[2]
elif argc == 2:
start_date = argv[1]
end_date = argv[1]
elif argc == 1:
print "specify start and end date."
sys.exit()
else:
flags = parser.parse_args(argv[3:])
CLIENT_SECRETS = os.path.join(os.path.dirname(__file__),
'client_secrets.json')
FLOW = client.flow_from_clientsecrets(
CLIENT_SECRETS,
scope=[
'https://www.googleapis.com/auth/calendar',
'https://www.googleapis.com/auth/calendar.readonly',
],
message=tools.message_if_missing(CLIENT_SECRETS))
storage = file.Storage('sample.dat')
credentials = storage.get()
if credentials is None or credentials.invalid:
credentials = tools.run_flow(FLOW, storage, flags)
http = httplib2.Http()
http = credentials.authorize(http)
service = discovery.build('calendar', 'v3', http=http)

y = datetime.date.today().year
d = datetime.datetime.strptime(start_date, '%m%d').date()
e = datetime.datetime.strptime(end_date, '%m%d').date()
d = d.replace(year=y)
e = e.replace(year=y)
summaries = pick(summary_pool)
while d <= e:
for tpair in scheduled_times:
stime, etime = tpair
stimestr = tstr(d, stime)
etimestr = tstr(d, etime)
s = summaries.next()
citem = {
"start":{"dateTime": stimestr},
"end": {"dateTime": etimestr},
"summary": s,
"location": "自室",
"description": "Created with cal3.py",
"colorId": "5",
"transparency": "transparent",
"reminders":{
"useDefault": False,
"overrides": [
{
"method": "popup",
"minutes": 5
}
]
}
}

try:
events = service.events().insert(calendarId='primary',
body=citem).execute()
except client.AccessTokenRefreshError:
print ("The credentials have been revoked or expired, "
"please re-run the application to re-authorize")

d += datetime.timedelta(days=1)
print "Following events are created.", events

def tstr(d, t):
hour, minute = map(int, t.split(':'))
t1 = datetime.time(hour, minute)
dt = datetime.datetime.combine(d, t1)
return dt.strftime('%Y-%m-%dT%H:%M:00+09:00')

if __name__ == '__main__':
main(sys.argv)








そしてUbuntu 14.04にしたよ

CUDA 6.0がうまく動作する確証が持てなかったのでずっとUbuntu 12.10のままで頑張っていたのだが、Askubuntu.comのこの質問の最初の答えを見ると、どうやらインストールが可能なようなので、アップグレードを行うことにした。

このリンクにある通りの作業を行ったら無事にインストールできた。ドライバをインストールする段階で、スクリプトが対話的にneoveauドライバを無効にする設定を行うかどうか尋ねてくれるので、YESと答えておけばnouveauの抹殺も手間いらずで行える。ただし、.runパッケージからのインストールなので、debianのパッケージシステムにCUDAの存在が認識されていない状態になっているのが気になる。後で.debパッケージからの再インストールを試みた方がいいかもしれない。

あと、既知の問題として、14.04へのアップグレード後、キーボード配列が英語配列になってしまうという現象があるようだ。実際自分のマシンでもそうなってしまい、若干調べると

Ubuntu 14.04 betaでキーボードレイアウトを日本語に戻す ibus-mozc編

ubuntu-gnome 14.04 (ibus-mozc)で日本語キーボードを使う

あたりにmozcの場合の対処方法は書いてある。私はまだAnthyのままなので、これらの記事を参考に

/usr/share/ibus-anthy/engine/default.xml

をエディターで編集し、

<layout>default</layout>

となっている行を

<layout>jp</layout>

と変更した。

これでも再起動しただけでは英語配列のままだったが、全角/半角キーを押すことで、半角モードでは日本語配列で通常のアスキー文字、全角モードでは日本語入力が可能になった。ただし、Control+Spaceとの絡みで、Control+Spaceを押さないと半角/全角キーもただバッククォートが入力されるだけになったり、また画面上のキーボードインジケータは日本語モードでもEnのままだったり、まだまだ挙動不審である。
本当は全角半角キーはEscapeにマップしてしまいたいのだが、泥沼にはまりそうなので、これでとりあえず我慢しておく。

12.xまでのときはWindowsを使い「こなせる」レベルの人にだったらUbuntuを試しに薦めることも可能だったが、日本語入力がこういう状態だと、さすがに他人には薦められない。インストール直後から普通にキーボード通りの文字が打てて日本語も入力できるというごく当たり前の状態が回復されることを切に願う。


プロフィール

GM3D

Author:GM3D
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
FC2カウンター
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。