読みました:年収は「住むところ」で決まる ─ 雇用とイノベーションの都市経済学
shoeihidoさんの
に触発されて、「年収は「住むところ」で決まる-─-雇用とイノベーションの都市経済学」
を買って読んでみました。
結論:かなり面白かったです。読む価値あります。
すらさんありがとう!良い本に出合いました!
だいたいまとめると
1) 先進国で低付加価値の製造業が破壊(特に雇用が)されるのはもう避けられない。その代わりに、アイデアや斬新さ、世界を変えるようなイノベーションで駆動する産業が先進国の経済をドライブする。
2) イノベーション駆動の産業は人・組織のつながりでより加速するので、ひとところに企業や優秀な人材があつまる(イノベーションハブ)。集まることでよりハブは強くなるので、その集まった地域だけが急速に地位を向上していくし、イノベーションハブに引き寄せられる優秀企業はそこから抜け出ることがなくなる*1。 人の面でも、イノベーションハブの企業のビジネスは個々人の知的生産性の高さで勝負しているので、優秀な高給取りが集まってくる*2。
3)イノベーション産業自体は少数精鋭の高給取りが主役なのでマスを支えることはできないが、イノベーションハブを支える地域経済(スーパーとかレストランとかお医者さんとかクリーニング屋さんとかその他もろもろ)を急速に潤すことができて、かつこの波及効果が製造業よりもずっと大きい。そのため、イノベーションハブでは「すべての知的階級と職層の」給料(と物価)が上昇する。
4) 一方、イノベーション産業から取り残された場所(「ラストベルト」)は相対的に経済的に沈んでいく。このながれをひっくり返すための処方箋はいまだ存在しないし、つまりイノベーションハブを狙って作ることは難しい。
5) 沈みゆく地域から脱出するのは、知的階層の上位に属する人たちがメイン。苦しい目にあう下位の人たちは、情報断絶による機会喪失や、経済的困窮により移住したくてもできないなどの理由でその場所に縛り付けられる。これは比較的引っ越しの多いアメリカでもそうなっている。
感想
・一時期、「フラット化する世界」が流行したわけですが、現実には格差は国単位どころか地域・都市単位で発生している状況ですね(東京vs地方)。しかしながら先進国の発展のためには格差を助長するイノベーションハブにますます栄えてもらってもっと税収を上げて国全体に還流させる必要があるという・・・
・アメリカの強さの一つとしてイノベーションハブが多数あること、があるのかなと。日本(東京)、韓国(ソウル)、フランス(パリ)、イギリス(ロンドン)などはハブが一つしかない(あるだけましですが)から、そこに一極集中する。ドイツは伝統的にいろいろ分散しているんですが、その代わりに圧倒的なハブがない。
・日本だと愛知・名古屋圏が「製造業(自動車)のイノベーションハブ」としての機能を維持していると思うのですが、これは何か例外な仕組みが回っているのでしょうか?それともトヨタ系列が痛みにたえているだけ?
・これを見た後に今回のアメリカ大統領選挙、そしてトランプ大統領の「アメリカというかラストベルトへの製造業回帰(と雇用創出)」を切実に必要とする支持層、まだハネムーン期間なのにすでに険悪な対応をとる東西海岸部とそこにベースを置くメディア、なんともなるほど感というか。*3
Installing CUDA8+CUDNN5.1+Torch on CentOS7 (Japanese/English mixed post)
ほぼ真っ白なCentOSだとあまり情報がないので、自分用のメモもかねて忘れないうちに。
I found there are few posts about CUDA8 + GPU-enabled Torch on 'vanilla' CentOS. Hope this post helps somebody...
基本ライブラリ群のインストール (Installing very basics)
sudo yum install emacs nano wget git gcc make cmake openssl-devel bzip2-devel readline sqlite-devel hdf5-devel
他にも何かいるかも。
Maybe I forget some libraries...
python
pipはget-pip.pyを持ってくる
Get PIP by get-pip.py :-)
wget https://bootstrap.pypa.io/get-pip.py
python get-pip.py
pyenvをgit clone
Cloning the pyenv. I do not use virtualenv so far (I do not fully understand the benefit of virtualenv)
git clone https://github.com/yyuu/pyenv.git ~/.pyenv
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
pythonは今後も考えて3系で進めます。
Use python 3.X based on my personal preference.
pyenv install 3.5.0
pyenv shell 3.5.0
pip install numpy
pip install scipy
pip install matplotlib
pip install pandas
CUDA, CUDNNインストール (Installing CUDA toolkit and CuDNN)
CUDAインストール
事前に、DKMSというライブラリを手動で確保する. Nouveauドライバをblacklistしないといけないかもしれません。ランタイムレベルは変えなくてもいけました。
Install a library called DKMS manually. Maybe you need to disable 'nouveau' drivers by blacklisting.
wget ftp://rpmfind.net/linux/epel/7/x86_64/d/dkms-2.3-1.20161202gitde1dca9.el7.noarch.rpm
NVIDIAからインストールパッケージ(network)をダウンロードします。
Download the CUDA toolkit from the NVIDIA homepage.
sudo rpm -ivh cuda-repo-rhel7-8.0.44-1.x86_64.rpm
sudo yum clean all
sudo yum install cuda
path設定
Setting the PATHs.
echo 'export PATH="/usr/local/cuda-8.0/bin:$PATH"' >> ~/.bashrc
echo 'export LD_LIBRARY_PATH="/usr/local/cuda-8.0/lib64:$LD_LIBRARY_PATH"' >> ~/.bashrc
source ~/.bashrc
CUDNNインストール
NVIDIAからユーザ登録してCUDNNのパッケージを確保。展開してコピーする。
You first need to register (for free) to utilize CuDNN. After that, get the tgz of the CuDNN. Extract and copy it to CUDA library directory. Easy.
tar -xvzf cudnn-8.0-linux-x64-v5.1.tgz
sudo cp -a cuda/lib64/* /usr/local/cuda/lib64/
sudo cp -a cuda/include/cudnn.h /usr/local/cuda/include/
Torch/Luaのインストール
あえてLUA (not LUAJIT)をインストール。
We install LUA, not LUAJIT. LUAJIT is memory-limited.
git clone https://github.com/torch/distro.git ~/torch --recursive
cd torch/
bash install-deps
TORCH_LUA_VERSION=LUA52 ./install.sh
必要なモジュール群をインストール.
Install modules by luarocks. Order matters.
luarocks install image
luarocks install tds
luarock install cwrap
luarock install torch
luarock install optim
luarocks install nn
luarocks install nngraph
luarocks install cutorch
luarocks install cunn
luarocks install cudnn
luarocks install hdf5
luarocks install luautf8
luarocks install threads
luarocks install penlight
luarocks install bit32
これでTorchでDeepぶん回せますね!
Now you are ready to rock with Deep NN on Torch!!
C++学習記(5): boost mpi (+openmpi) on multiple CPUs (machines)
Boost MPIに複数コア分散計算のお仕事は終わったので、いよいよ複数マシンによる盛大な負荷分散をやろうと思う。
簡単じゃない?簡単じゃない
hostsを指定するファイルを作って
# nodes_for_MPI.txt
host.1.xx.yyy cpu=4
host.2.xx.yyy cpu=2
mpirun起動時に指定するのみ。簡単じゃない?
mpirun -np 6 --hostfile nodes_for_MPI.txt ./helloBoostMPI
ORTE was unable to reliably start one or more daemons.
This usually is caused by:
はい死んだー。
sshで直接コマンド渡すとき~
のdiagnosisに従うと、まず2番目、ssh経由でコマンド渡すときのpath設定があってなかった。
ということで
ssh-env - ssh実行時に環境変数を設定/変更したい - spikelet days
に従って、/etc/ssh/sshd_configの修正と.ssh/environmentの作成。
pathとかはすべて一つにまとめて直書きする必要があります。
sudo service sshd restart
sshdをリスタートして・・。
mpirun -np 6 --hostfile nodes_for_MPI.txt ./helloBoostMPI
ORTE was unable to reliably start one or more daemons.
This usually is caused by:
まだできない。
ファイヤーウォール氏~
--mca plm_base_verbose 10 をオプションとしてつけると、TCP/IPコネクションの問題ぽい。ファイヤーウォールの設定ぽいな・・・。
sudo /etc/init.d/iptable. stop
mpirunをたたく側のマシンのiptableをカット。まあ、社内ファイヤーウォール内だから大丈夫でしょう。。。
mpirun --hostfile nodes_for_mpi.txt ./helloBoostMPI
My rank =1 of 6
My rank =4 of 6
My rank =0 of 6
My rank =5 of 6
My rank =2 of 6
My rank =3 of 6
やったねたえちゃん!
C++学習記(4): boost mpi (+openmpi)
ようやく本来の目的であった並列計算に。
最初はOpenMPによるお手軽並列計算を使ってみたのですが、メモリの共有の切り分けがうまくいかず、並列度を上げれば上げるほど遅くなっていく残念な結果に・・・
ということで、結局急がば回れ、MPIでちゃんと書くほうが確実。
準備
まずはOpneMPIをインストールして、続いてMPIを使いやすくしたboost mpiを利用するためにboostを(再)インストール。
情報源としては↓がいい感じです。
ただ、boost 1.61だとusing mpi ;がうごかないことが何度もあったので注意。こういう時は本家(Getting started - 1.61.0 )を見に行って、それに従うのが吉。
結局、.user-config.jamとproject-config.jamの両方で
using mpi : your/own/path/to/opnempi/bainaries ;
の形式の1文を追加して突破しました。
CMake
CMakeLists.txtは以下のような感じになりました。ただ、環境によって動かなかったりするのも経験したので、これを下敷きにしていろいろ試行錯誤するしかないみたいです。もっとスマートな書き方とかがあったら教えてください。
cmake_minimum_required(VERSION 2.8)
project(boostmpi_test)add_definitions("-Wall -std=c++11")
add_definitions("-O3")set( BOOST_ROOT "/usr/local/boost-1.61.0_gcc-4.9.2_mpi")
FIND_PACKAGE(Boost 1.6 COMPONENTS mpi serialization REQUIRED)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
set( CMAKE_C_COMPILER mpicc )
set( CMAKE_CXX_COMPILER mpicxx )add_executable(helloBoostMPI helloBoostMPI.cpp)
add_executable(testScatter testScatter.cpp)
add_executable(testBroadcast testBroadcast.cpp)
add_executable(testGather testGather.cpp)TARGET_LINK_LIBRARIES(helloBoostMPI ${Boost_LIBRARIES} -lboost_mpi -lboost_serialization)
TARGET_LINK_LIBRARIES(testScatter ${Boost_LIBRARIES} -lboost_mpi -lboost_serialization)
TARGET_LINK_LIBRARIES(testBroadcast ${Boost_LIBRARIES} -lboost_mpi -lboost_serialization)
TARGET_LINK_LIBRARIES(testGather ${Boost_LIBRARIES} -lboost_mpi -lboost_serialization)
サンプル
せっかくなので、動作と使い方確認用に作成したソースを公開しておきます。
基本的に
を焼き直しただけなんですが・・・
C++ 学習記(3): vector
C++といえばvectorというくらい、配列は全部vectorにするのがいいっぽい。
どこで見たのか覚えていないのですが、webで見つけた資料を基に
vectorの挙動を調べるためのコードを書きました。ふーんって感じ。
#include <iostream>
#include <vector>
#include <string>
using namespace std;typedef vector<float> fvec;
void print(const char* str, vector<int> &v){
if(v.empty()){
cout << "コンテナ" << str << "は空です。" << endl;
cout << str << "の要素数 is " << v.size() << endl;
} else {
vector<int>::iterator it;
cout << str << "の要素数 is " << v.size() << endl;
for (it = v.begin(); it != v.end(); it++){
cout << " " << *it;
}
cout << endl;
}}
void print(const char* str, fvec &v){
if(v.empty()){
cout << "コンテナ" << str << "は空です。" << endl;
cout << str << "の要素数 is " << v.size() << endl;
} else {
fvec::iterator it;
cout << str << "の要素数 is " << v.size() << endl;
for (it = v.begin(); it != v.end(); it++){
cout << " " << *it;
}
cout << endl;
}}
int main(){
int i1;
vector<int> v1;
vector<int> v2(10, 3);
fvec fv1;
fvec fv2(5, 3.5);/* initalize */
cout << "*** initialize a vector ***" << endl;
print("v1", v1); // should be empty
print("fv2", fv2);
for(i1 = 0; i1 < 10; ++i1){
v1.push_back(i1);
fv1.push_back( (float)i1 * 1.1 );
}
cout << "# v1.push_back(i1);" << endl;
print("v1", v1);cout << "# fv1.push_back( (float)i1 * 1.1 );" << endl;
print("fv1", fv1);cout << endl;
cout << "*** clear a vector ***" << endl;
fv1.clear();
cout << "# fv1.clear()" << endl;
print("fv1", fv1);
/* vector of vectors */
cout << endl;
cout << "*** initialize a vector of vectors ***" << endl;
vector<fvec> vector_of_fv;
for(i1 = 0;i1 < 3; ++i1){
fvec new_fv(fv2);
vector_of_fv.push_back(new_fv);
}
// check if the above push_back is reference or deep copy
fv2[0] = -1.9;cout << "# fvec new_fv(fv2);" << endl;
cout << "# vector_of_fv.push_back(new_fv);" << endl;
print("fv2", fv2);
for(i1 = 0;i1 < 3; ++i1){
string str = "vector_of_fv[" + to_string(i1) + "]";
print(str.c_str(), vector_of_fv[i1]);
}for(i1 = 0;i1 < 3; ++i1){
vector_of_fv[i1][i1] = -1.2 * i1;
}
cout << "# vector_of_fv[i1][i1] = -1.2 * i1;" << endl;for(i1 = 0;i1 < 3; ++i1){
string str = "vector_of_fv[" + to_string(i1) + "](modified)";
print(str.c_str(), vector_of_fv[i1]);
}
}
出力結果
$ ./a.out [~/projects/CPP]
*** initialize a vector ***
コンテナv1は空です。
v1の要素数 is 0
fv2の要素数 is 5
3.5 3.5 3.5 3.5 3.5
# v1.push_back(i1);
v1の要素数 is 10
0 1 2 3 4 5 6 7 8 9
# fv1.push_back( (float)i1 * 1.1 );
fv1の要素数 is 10
0 1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9*** clear a vector ***
# fv1.clear()
コンテナfv1は空です。
fv1の要素数 is 0*** initialize a vector of vectors ***
# fvec new_fv(fv2);
# vector_of_fv.push_back(new_fv);
fv2の要素数 is 5
-1.9 3.5 3.5 3.5 3.5
vector_of_fv[0]の要素数 is 5
3.5 3.5 3.5 3.5 3.5
vector_of_fv[1]の要素数 is 5
3.5 3.5 3.5 3.5 3.5
vector_of_fv[2]の要素数 is 5
3.5 3.5 3.5 3.5 3.5
# vector_of_fv[i1][i1] = -1.2 * i1;
vector_of_fv[0](modified)の要素数 is 5
-0 3.5 3.5 3.5 3.5
vector_of_fv[1](modified)の要素数 is 5
3.5 -1.2 3.5 3.5 3.5
vector_of_fv[2](modified)の要素数 is 5
3.5 3.5 -2.4 3.5 3.5
参考文献
完全にC++は未知だけどもJavaなら結構経験積んでいたので、私の知り合いの中で最もプログラミングに長けた大先輩におすすめしていただいた
を買いました。とりあえず、わからないことがあったらこれにあたってみると、1つくらいは例が載っているのでだいたい乗り切れています。*2
C++ 学習記(2): cmake
IDEが使えない可能性を考慮して、C++はlibtool chainかcmakeで何とかしようと思っていた。
で、とりあえずcmakeが簡単そうだったのでやってみる。
情報源は
Learning CMake <-- これ素晴らしい!
いま、cmake_testというディレクトリ内に
HelloCPPWorld.cppというC++ファイルだけが存在している。
このとき、最低限として以下の内容をCMakeLists.txtというファイルに書く。
HelloCPPWorld.cppを作っておく。
Add_definitions("-Wall -std=c++11")
Add_executable(Main HelloCPPWorld.cpp)
// HelloCPPWorld.cpp
#include <iostream>int main(){
std::cout << "Hello CodeLite World";
return 0;}
この状況で、
cmake . <-- makefileを生成
make
とするとMainという実行ファイルができる。
cmakeはヘッダファイル(hpp)の必要なものを指定したパスから買って見つけてくれるので、MakeFileより書くのが楽。
C++ 学習記(1): まずは環境確認整備
業務の都合でいままで書いたことのないC++を使わざるを得なくなった。
業務のほうは既存のC++コードを書き換える方向なので、まあなんとかなるだろうと思っているんだけど、スクラッチから起こすことができないので
makeの書き方も-Iや-Lオプションの意味もautomakeも何もわかっていない。
ということでやばいだろうということでよちよち勉強していくことにする。
やらないといけないであろうこと
MakeFileの読み方書き方、automake, cmake
コンパイルオプション
ldconfig, LD_LIBRARY_PATHの意味と設定方法を理解する
OpenMP / MPIによる並列化
参考文献
完全にC++は未知だけどもJavaなら結構経験積んでいたので、私の知り合いの中で最もプログラミングに長けた大先輩におすすめしていただいた
を買いました。とりあえず、わからないことがあったらこれにあたってみると、1つくらいは例が載っているのでだいたい乗り切れています。*1
設定
プログラム経験: Java(メイン、10年以上), Python(ここ2年ほどメインで使ってる)
OS: ubuntu14.04 on VMware
エディタ: emacs
IDE: JetBrains IntteliJ IDEAとPycharmがないとJavaもPythonもかけない
IDE絶対ほしいけど、JetBrainsのC++って有償なんだよね、確か・・・
現在の状況
何が入っているか確認するのもあってapt-get installでそれっぽいライブラリを指定してみる。
ちょっと探すと
という記事が見つかったので、載っているやつはインストールしておく。
Hello, world
まずはhello world.
(hello.cpp.cpp)
#include <iostream>
#include <cstdlib>int main(){
std::cout << "hello world" << std::endl;
return 0;
}
コンパイルして実行。
% g++ hello_cpp.cpp
% ./a.out
*1:const参照とか&, *の使い方とか私にとっては完全に悪夢なので、毎回見ています