doridoridoriand’s diary

主に技術的なことを書いていく予定(たぶん)

最速でAPIをつくろう

写真のフランク・シナトラとは関係ないよ(たぶん)

Androidアプリを書いていて、最初はAPIいらないかと持っていたのですが、今後の実装を考えていくうちにどう考えても辛さしかないわって感じになったので速攻で作りました。
個人的にはAWSAPI Gatewayとか試したかったんですけど、今回はあまり時間がなかったので。。
(というか日程的にバックエンド開発に時間を割けないorz)

よって一番慣れているもので作りましたとさ

実際にはクローラーが稼働していて、そいつらが読み取ったデーターがMySQLにたまっている感じを想像していただけるとわかると思います。まあ今流行りのクローラーです

とりあえずgemを入れましょう

gem install sinatra

次にサクッとコードを書きます

例えばDBのテーブルがこんなかんじだったとしまして

create table `hogehoge_items` (
  `id`            int(10)      unsigned not null,
  `hoge_id`       int(10)      unsigned not null,
  `title`         varchar(255) not null,
  `link`          varchar(768) not null,
  `published`     varchar(255) not null,
  `updated`       varchar(255) not null,
  `content`       varchar(255) not null,
  primary key(`id`)
) engine=InnoDB default charset=utf8;

シンタックスハイライトすんじゃん!!びっくり!!

取り乱しました。すみません。出来ないものだとばかり思い込んでいたので。。。

DBスキーマそのまま貼っつけましたが皆さんわかると思うのでこのまま行きます

次に肝心のコードです

require 'active_record'
require 'sinatra'

db_config = YAML.load_file(File.expand_path(File.join(__FILE__, 'config', 'database.yml')))
ActiveRecord::Base.establish_connection(db_config['db']['production'])

set :root, File.expand_path(File.join(__FILE__, '..', 'static'))

get '/' do
  erb :index
end

get '/news/:hoge_id' do
  content_type :json, :charset => 'utf-8'
  entries = GoogleAlertItems.where(hoge_id: params[:hoge_id]).order('updated DESC').limit(10)
  entries.to_json(:root => false)
end

本当をいうと今回実装したのと全然構造違うのですが、説明用に変えて書いています。 とりあえず上から説明していきます

require 'active_record'
require 'sinatra'

大丈夫ですね。普通にimport#includeといった他の言語にもよくあるライブラリの読み込みです

db_config = YAML.load_file(File.expand_path(File.join(__FILE__, 'config', 'database.yml')))
ActiveRecord::Base.establish_connection(db_config['db']['production'])

ActiveRecordを単体で叩けるように設定を読み込んでいます。db_config['db']['production']部分をproductionからdevelopment変えたりすることで開発環境と本番環境を分けたりなど、色々と便利なのですが、とりあえず今回はそこまで凝ったことしなくていいので
あ。ここでdatabase.ymlは既に存在していること前提で話しています(笑)

set :root, File.expand_path(File.join(__FILE__, '..', 'static'))

Sinatraは静的ファイルのディレクトリの場所を変更することが可能です。今回は色々な関係でstaticというフォルダを指定しています

get '/' do
  erb :index
end

get '/news/:hoge_id' do
  content_type :json, :charset => 'utf-8'
  entries = GoogleAlertItems.where(hoge_id: params[:hoge_id]).order('updated DESC').limit(10)
  entries.to_json(:root => false)
end

メインディッシュですね。Sinatraの特徴はMVCアーキテクチャーに則っていないことです。乱暴に言うとCしか持っていません。そしてこれはルーティングを書いているだけです。 ちゃんと設計してあげれば立派なMVCフレームワークになるのですが、ならRails使えよって話で(笑) ちなみにSinatraをベースにMVCアーキテクチャーを持たせた設計にしてあるのがPadrinoってやつです
僕はいまいちRailsに比べての優位な部分を見いだせていないので使ったことないです。すません

get '/' do
  erb :index
end

これはサイトのトップディレクトリに来たらstaticsフォルダーにあるindex.erbrenderする処理を書いています。ちなみにhamlだろうがslimだろうが適切なgemを入れてあげれば対応できます

get '/news/:hoge_id' do
  content_type :json, :charset => 'utf-8'
  entries = GoogleAlertItems.where(hoge_id: params[:hoge_id]).order('updated DESC').limit(10)
  entries.to_json(:root => false)
end

これはなんかややこしそうですね。しかし分解して読み解けば簡単です

get '/news/:hoge_id' doでURLに含まれている/news/以下の文字列を読み取ります。よって

/news/yoshioというURLに対してアクセスが来た場合、 yoshioという文字列がsinatra側に渡されることになります

GoogleAlertItems.where(hoge_id: params[:hoge_id]).order('updated DESC').limit(10)

ここで何をしているかというと、URLから読み取った文字列をActiveRecordに渡して、hoge_idと一致するものを持ってきて更に更新日時が新しい順にし、そして最大10件持ってくるという処理をしています

entries.to_json(:root => false)

説明不要かもですが、みんなだいすきJSONを生成しています。最終的にこいつが結果としてrenderされます

今回はgetしか使っていませんが、もちろんpostupdatedestroyも可能です。 長くなったのでここで終わりにしますが、次回はunicornでデーモン化した話を書きたいです
(ちゃんと次回があればの話だがなっ!)

あ。。。GPUの連載止めてた。。書きます

Androidを久々に書くなど

輪講の準備などでちゃんとかけませんでした。その上輪講発表ボコボコマンだったので、昨日は投げやりでしたorz

写真のコードから現在のJava力を察していただけると幸いです。勉強せんと。。 普通に焦燥感しかない

Androidのコードを真面目に触ったのはAndroid2.X系のやつしかなく、もちろんFragmentなんて存在せず、 フツーにMainAvtivityとかで通信系の処理を(非同期ではなく。今考えれば、それは当時でもバッドプラクティスなんですけど。。)やっちゃってたりしたので、 もう完全に置いて行かれているわけです。てかそもそも最近は動的型付けのやつしか書いていなかったし。。

しかしもう言い訳していられない状況になったので、今日向き合ってみました

そもそもFragmentってなんぞや

Fragment

一番下のレイヤーにActivityがあり、その一個上のレイヤーがFragmentとなります。本当はViewを持たないFragmentとかを作ることが出来るらしいですが、僕はまだそのレベルではないので。。

つまり、Fragmentを複数作っておけば、Activityが1つでも表示する内容をActivityを変えることなく変更することが可能になるわけです。

MainActivityからintentしてSubActivityを呼び出すとかしなくていいわけですね。なんかモダンっぽい ちなみに横からメニューが出てくる系実装をしたければFragmentの利用は必須っぽいので今のうちに慣れておこうと思って勉強しました

今のところガワしか出来ておらんのだけれど。。 まあ色々コードを書くと以下のようなViewが完成します

Android Moc

そのうちちゃんとしたコードをGistであげたいですね(リポジトリ作るほどではないので)

それにしてもAndroidStudioいいわ。ベータ版使っていた時はこれマジで大丈夫か(笑)って思ったときもあったけど

まあちょっと困るとすればCocosIDEと見分けがつかなくなるくらい(同じIntellij IDEAなので)

今使ってるHUGOのテーマ使いづらいところが色々とあるのでそのうちテーマ自作しよう。。
コードのシンタックスハイライト出来ないの致命的だし

帰宅してから更新するスタイルがまだ身についていないorz

もう完全に写真無関係だろっていうね。 でもなんか写真ないと寂しいのでつけております。

やっぱJavaは出来て当たり前の言語なんだよなっていう無言の圧力をヒシヒシと感じながら生活しています。 動的型付けの言語ばっか書いているのイクナイ(って言いながら最近動的型付けばっかなんだけど)

個人的にプログラミング言語習得をするときに守っていることがあって、絶対に最初はフレームワークを使わないっていうことを守っています。(守っているというか心がけています)

まあ色々書きたいことはあるんだけどただの愚痴になってしまうので。。。

1つだけいうとフレームワークありきで言語を学習してしまうと、そのフレームワークしか使えないコピペエンジニアになってしまう危険性が格段に高くなってしまうってことですね。てかそれに尽きると思っています

週末更新出来なかったorz

※写真には特に意味ありません

結局週末更新できなかったorzorzorz
金曜日に久しぶりにある先輩達と飲んで、飲み過ぎて結局朝まで飲んでて、その反動が土曜日に来て一日まともに行動できず、 日曜日の午前中も調子がでなくて起きられず、午後から輪講発表用の資料作成で全部潰れるというつまらない週末を過ごしておりました。

ていうかすごいうんこみたいな生活しているなwまあ事実うんこだから仕方がないw

どうでもいいんですけど、
ThreadSafeなプロセスをThread並列させてもとくに問題ないじゃないですか。当たり前ですけど。だけどThreadSafeなプロセスをThread並列させて、更にProcess並列させた場合、ThreadSafeはちゃんと保証されるんですかね。まあCUDAの話なんですけど。。
なんかCUDAそうじゃないような気がしているんですよね

もう夏バテした感

朝起きたら既に30℃超えていて本格的な夏到来ってかんじですね。僕が小さいことこんなに暑くなること珍しかった気がしますけど、最近では普通になりましたね

久しぶりに何も考えずに文章をだらだら書こうかなと思います。
昔は色々な分野で、自分の考えと違う人たちや、自分が正しいと考えていることとは異なった考えの人たちに対して、自分の立場を説明して、そして自分の考えに同調・行動して欲しいみたいな気持ちが強かったのですが、 今は全然そんなことなくて、むしろみんな色々!多様性!うまく言っていればそれでいいじゃん!みたいな感じて他人に対して 過度に深く知ろうとか、自分の考えを説明しようとかしなくなりました。 これが色々考えた末の結論だと思ってはいるのですが、単純に面倒くさくなっただけだったりして(笑)

まあ面倒くさくなったことも一理あるんですけどね

とりあえず僕は、自分が楽しく生きられていて、ついでに、自分に関係のある身の回りの人が概ね幸せで、楽しく生きられていればそれで良いかなってなっています。
自分ひとりで出来ることには限界が必ずありますから、とりあえず身の丈にあったことをやっていこうと思います

もちろん

身の丈にあった≠成長しない

ではないですよ。
はい、気持ち悪いナルシストポエムの完成〜(ポエムでもねえけどw)

Raspberry Piをキオスク化してみた

写真ダウンロードサイトpixabayという素晴らしいサイトを見つけてしまった。ぱくたそと共にありがたいサイトの一つですね

Raspberry Pi

Raspberry pi

技術系の話に敏感な人で知らない人はいないんじゃないかと思われるくらい浸透しているRaspberry Piですが、今のところ今すぐ買いたくなるようなメリットを感じられずに結局買っていませんでした。 なんかサーボモーターとかステッピングモーターをつないでいじっている友達は周りにいるのですが、あまりそういうことしないし(笑)

・・・

ひょんなことから、出欠管理の表(Webアプリ)を表示させておきたいという相談をされて、また既にその相談をしてきた友達がraspberry Piを持っていたことから、タイトルのようなことをするに至りました。

僕個人としてはRaspbianってベースはDebianなんだから、update-rc.dとかでテキトーに起動スクリプト書けばいいんじゃねーとか思っていたのですが、もっと簡単に出来る方法があったので、書きます。
(ちなみにDebianではもうupdate-rc.dで起動プロセスいじるのは非推奨らしいです。今はinsservだそうです。知らんかった)

最初の方針は、

  • chromiumの起動スクリプト書く(chromiumというファイル名で保存)
  • 書いたスクリプト/usr/init.d/配下に移動 & chmod 755 chromium
  • sudo update-rc.d chromium Defaults で登録
  • ついでにちゃんと登録されているか sudo find /etc/ -name "*chromium" で確認

でおkだと思っていたのですが、まあとりあえずうまくいかないので(笑)
次にchromiumがsudo権限で動かないことを知らなくて、ググったとおりにchromiumの起動スクリプトを改変
(具体的には、起動スクリプトの最後らへんに書かれている、exec 〜 "$@"以下に --user-data-dirという記述を追加。詳しくは『chromium root実行』などでググるとすぐ出てきます)

をしたものの、やはりうまくいかない。これは困ったなwと思いながらその友達から

パン屋のサイトがめっちゃ簡単そうにやってたよ

と教えてくれたので、教えてもらったこのサイトを見てみると。。

まずパン屋では無いことがわかりましたね(笑)
という僕も最初勘違いして、パン屋に負けたのか。。としばらく凹んでましたけど。。

結論としてはXwindowSystem側のAutoStart設定を利用する形になります。
ホームディレクトリ配下に存在する.config内部のlxsession/LXDE/autostartファイルを作成して、 その中にchromiumと書けば解決しました

ちなみにchromiumは全画面かつそのサイトしか表示できないキオスクモードが正式に存在し、コマンドラインから

chromium -kiosk

などとうつとキオスクモードになります。また更に

chromium -kiosk "表示したいサイトのアドレス"

とすればサイト指定で(設定で指定しなくても)キオスクモードを実行できます。既知の人からすれば何今更言ってんだよwwwって情報かもしれませんけど(笑)

Raspberry Piが欲しいかは以前として微妙なままですが、久しぶりによく知らないハードを触って楽しかったです

GPUコアに関して

前回コード書かずに終わったので今回はコードを書いて示しながら説明したいですね(希望)

ちなみに前回の話はこちら

CUDAコアに関して

GPUはSM(Streaming Multiprocessor)というのが内蔵されており、この中に

  • 命令ユニット
  • 演算器(ALU(Arithmetic Logic Unit)とか)
  • レジスタ
  • キャッシュ(シェアード・コンスタン・テクスチャメモリ)

が入っています。ちなみにTesla世代とFermi世代で相当構成が変わっているので、(FermiにはSMの外にL1, L2キャッシュがあるなど) 共通部分のみ記述しています。

さらにこのSMの下に、SP(Scalar Processor)と呼ばれる、ALUをまとめたものが存在します。

コードを書くにあたってBlockとThreadという概念も登場するのですが、後で説明します。

ここでTeslaK20のGPU情報を見てみましょう

--- General Information for device 0 ---
Name:  Tesla K20c
Compute capability:  3.5
Clock rate:  705500
Device copy overlap:  Enabled
Kernel execution timeout :  Disabled
--- Memory Information for device 0 ---
Total global mem:  5368512512
Total constant Mem:  65536
Max mem pitch:  2147483647
Texture Alignment:  512
--- MP Information for device 0 ---
Multiprocessor count:  13
Shared mem per mp:  49152
Registers per mp:  65536
Threads in warp:  32
Max threads per block:  1024
Max thread dimensions:  (1024, 1024, 64)
Max grid dimensions:  (2147483647, 65535, 65535)

この情報を見てみるとSMが13基あることがわかります。

そして見慣れないThreadとBlock, Gridが登場しました。(他にも見慣れない単語はたくさんあるのですが、とりあえず笑)

Thread

実際に計算を行う部分。つまりSPのことです

Block

Threadを束ねたもの。 Max threads per block: 1024と書かれているとおり、TeslaK20では1024個のThreadを1Blockとしています

Grid

Blockを束ねたものです

・・・

さっきの出力結果を見てみると、以下のような記述に疑問を持つと思われます。

Max thread dimensions:  (1024, 1024, 64)
Max grid dimensions:  (2147483647, 65535, 65535)

なんでカンマで区切られているんだ??そしてdimensionsってなんだ??

dimensionという単語から推測出来る通り、これは次元を持ちます

  • (i)ならば一次元
  • (i, j)ならば二次元
  • (i, j, k)ならば三次元

という記述をすることが可能です。

計算したい内容によって次元数は変わりますし、処理内容によっては二次元・三次元を一次元のように書くことが可能です

さて、コードを示そうと思いましたが、書くのにめっちゃ疲れたので今日はもうやめますorz

正直文字だけでは非常にわかりにくいと思われるので、また作図して載せます