2014년 9월 16일 화요일

First Steps with Celery

셀러리를 설치한지도 한달은 된것 같은데 이제야 셀러리의 첫단계를 완료하다니...

머 암튼...삽질을 했으면 기록을 남겨야 하니까..

일단 출처


환경

윈도우환경으로 Broker로는 RabbitMq 를 사용합니다.

시작하겠습니다.

분산컴퓨팅에서는 다음과 같은 구조가 가장 기본입니다.

사진출처 : Rabbit MQ

P : producer
C : consumer

Producer가 메시지를 전송하면 중간에 Broker(Hello)가 메시지를 Consumer에서 전달하는 구조입니다. 

일반적으로 생각하면 Producer는 클라이언트가 되어 요구를 전달하면 중간자가 그 메시지를 적당한 서버에 전달하는 구조인거죠.. 같은 말을 두번 하는거죠? ㅎㅎ

Application

첫번째로 우리는 Celery instance가 필요합니다. 이것은 Celery application 이라고도 불리고 "app"이라고 짧게 줄여 쓸기도 합니다.

tasks.py 라는 파일을 생성하죠

from celery import Celery

app = Celery('tasks', broker='amqp://guest@localhost//')

@app.task
def add(x, y):
    return x + y
Celery는 broker를 RabbitMQ 또는 Redis를 사용합니다. 원하시는 Broker를 선택하시면 되는데 기본적으로 해당 문서는 RabbitMQ 기반으로 작성되어있습니다.
해당 모듈은 add 라는 두개의 숫자를 더하는 하나의 함수만 존재합니다.
Running the celery woker server
tasks.py를 만든 위치에서 cmd 창에서 다음과 같은 명령어를 입력합니다.
$ celery -A tasks worker --loglevel=info
사실 이보다 먼저 행해져야 하는것이 Broker의 실행입니다. 이문서는 RabbitMQ를 기준으로 기술하고있습니다. RabbitMQ의 실행화면

celery 실행화면

Calling the task
task를 호출하기 위해서는 delay() 메소드를 사용합니다.
>>> from tasks import add
>>> add.delay(4, 4)
delay() 메소드의 return은 AsyncResult instance 이다. 이말은 단순히 4+4의 결과물인 8 만을 반환하지는 않는다는 말이다. 다음에서 더 자세히 보자
Keeping Results
tutorial을 하는데 왜 한두달이 걸렸냐고 묻는다면 바로 이 부분에서 막혀서 한동안 진전이 없어서였다고 말하겠다. 위에서 봤지만 delay() 메소드의 return은 AsyncResult instance 이다. 다시 말해서 이는 결과값도 비동기적으로 리턴할수 있는 구조체이다. 그렇다면 클라이언트가 메시지를 던지고 브로커가 워커에게 할당을 하는 과정이 메시지를 던지는 과정이라면 워커가 결과물을 브로커에게 던지고 브로커는 클라이언트에게 다시 던지는 과정이 결과물을 받는 과정이겠다. 여기서 중요한건 브로커가 비동기적 리턴을 들고 있어야 한다는 사실이다. 이러한 결과물 저장소를 backend라고 하고 celery에서는 backend를 SQLAlchemy/Django ORM, Memcashed, Redis, AMQP(RabbitMQ) 그리고 MongoDB 그외 당신이 원하는것으로... 하지만 우리는 Rabbit MQ를 사용하겠습니다.
그렇게 하기 위해서 위에서 작성한 tasks.py 파일의 일부분을 수정합니다.
app = Celery('tasks', backend='amqp', broker='amqp://')
>>> result = add.delay(4, 4)
ready()라는 함수는 프로세싱이 끝이 났는지 아닌지를 알려주는 함수입니다.
>>> result.ready()
False
get()이라는 함수를 통해서 원하는 8 이라는 리턴을 가져올수 있습니다.
>>> result.get(timeout=1)
8
여기가 막히는 부분이었는데
보시는 바와 같이 TimeoutError : the operation timed out.
에러 메시지를 뱉어낸다.. 아우... 약올라...

이 에러메시지를 해결하는 방법은 아래와 같다.

Configuration

해당 에러메시지를 이용하여 구글링을 했을때 항상 나오는 말이 설정에서 backend를 amqp로 설정하고 task result expires를 적당한 숫자로 입력하라고 한다. 
CELERY_RESULT_BACKEND = "amqp"
CELERY_TASK_RESULT_EXPIRES = 1000
그래서 실제로 설정부분에서 시키는 대로 celeryconfig.py 파일을 만들었다.
BROKER_URL = 'amqp://'
CELERY_RESULT_BACKEND = 'amqp://'
CELERY_TASK_RESULT_EXPIRES = 18000
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_SERIALIZER = 'json'
CELERY_ACCEPT_CONTENT=['json']
CELERY_TIMEZONE = 'Europe/Oslo'
CELERY_ENABLE_UTC = True
원문에서 해당 파일을 만들어서 환경변수 PATH 에 놓거나 current directory 에 저장하라고 했는데 두가지 방법을 사용해 보았을때 current directory 에 넣고해야 하는것 같다. path에 넣었을때는 사실 인식을 못해서 반복해서 에러를 뱉었던것 같다.
 그리고 tasks.py 파일의 일부분을 수정한다.
app.config_from_object('celeryconfig')
그리고 다시 실행한 모습니다.



참고로 amqp에 결과물이 저장되는 형태는 pickle, json, msgpack, yaml등을 사용할수 있으니 편한것을 설치하고 설정하면 된다.

우왕.. 이제 첫걸음을 떼다니...힘듬.




2014년 8월 28일 목요일

IPython notebook - RandomNumber

IPython을 설치 하고 QuantLib SWIG를 통해서 python 에서 QuantLib을 사용할수 있는 환경을 만들었으니 IPython notebook을 통해서 공부한 내용을 정리해 보기 위해서 연습한 첫날입니다.

지금까지는 맨날 설치에 관한 기고만 하다가 아주 오랜만의 내용이 들어 있는 포스트입니다.

일단 연습을 위한 강의를 하나 링크를 걸겠습니다.

http://vimeo.com/97010742

위링크는 Luigi의 블로그에서 IPython notebook 이 좋은 놈이군요 저도 연습해봐야겠습니다. 하면서 올린 동영상입니다. vimeo를 통해서 보시면 되겠습니다.

순서대로 하죠 IPython notebook 자체가 웹기반으로 움직이게 설계가 되어있는 만큼 서버를 구동해야 합니다. 말이 거창해서 서버 구동이지 ... 지난 포스트에서 IPython 설치하신데에 가셔서 ipython notebook을 실행하시면 되겠습니다.

pip를 통하여 설치하신분들은 cmd 창에 ipython notebook라고 치시면 됩니다.


anaconda를 통해서 설치를 하신분들은 시작-프로그램 에서 찾아서 ~~~

구동하면 다음과 같이 됩니다.



구동과 동시에 웹페이지 형식의 IPython notebook 이 시작 되었습니다.


목록리스트가 뜨게 되는게 ipython notebook을 구동시킨 폴더의 현재 상황을 보여줍니다. Random Number.ipynb 이라고 쓰인게 동영상속의 강좌를 수강한 결과입니다. ~~~

위 링크 강좌를 천천히 따라하세요 저와 같은 파일을 갖게 됩니다.

python의 세상은 정말 무궁무진 합니다. 열심히 합시다~~

강좌 중간에

mpl_toolkits

를 import 하는 부분이 나오는데 저도 그 모듈이 깔리지 않아서 .. 강좌를 듣다가 스톱하고는 설치 후 진행했습니다. 링크 걸어 드리겠습니다.

http://www.lfd.uci.edu/~gohlke/pythonlibs/

위 링크에서 Basemap을 검색하셔서 본인이 맞는 버젼을 설치하시면 됩니다.
mpl 이 가만 보니까 Mat Plot Lib 의 약자인가 봅니다. ㅎㅎ

감사합니다. 즐프~~

2014년 8월 23일 토요일

python Quantlib tutorial - Part2

이전 포스트에 이어서..

QuantLib을 빌드를 끝냈으면 다음으로 할일은 환경변수를 설정하는 일입니다.

환경변수에 다음을 추가 합니다.
QL_DIR 
    -quantlib이 설치된 경로를 지정합니다.
    -ex)  D:\QuantLib-1.2.1
INCLUDE
    - boost가 설치되어 있는 include 경로를 지정합니다.
    - ex) D:\boost_1_52_0


setup을 합니다.

QuantLib-SWIG\Python\setup.py  파일이 있는 경로에 가서 

$>python setup.py build

$>python setup.py test

$>python setup.py install

설치가 왼료되었습니다.

사실 swig Quantlib을 해보면서 빌드를 설치할때 까지 오래 걸린거 같습니다. 오프소스라는것이 본인이 스스로 설정을 해야 하는 부분이 많기 때문인것 같기도 하고 .. 환경변수를 설정하는것 또한 쉽지는 않더라구요 .. 



Very Easy: Find Yield to Maturity of a Bond from its Price[edit]

from QuantLib import *

effectiveDate = Date(30, 1, 1990)
terminationDate = Date(30, 1, 2000)

# The Schedule object determines the dates on which transactions occur.
s = Schedule( 
   effectiveDate, 
   terminationDate, 
   Period(Semiannual), 
   UnitedStates(UnitedStates.GovernmentBond), 
   ModifiedFollowing,
   ModifiedFollowing,
   DateGeneration.Backward,
   False
)

# FixedRateBond object's parameters
settlementDays = 3
faceAmount = 97.54
rate = 0.04 # this means 4%
redemption = 100.0 # this means 100% of the initial value.
todayDate = Date(24, 9, 1995) 

# Construct the object 
f = FixedRateBond( 
   settlementDays,
   faceAmount,
   s, # Schedule object
   ( rate, ), 
   ActualActual(), 
   Following, 
   redemption,
   todayDate
)

# The Bond's Yield to Maturity
f.bondYield( ActualActual(), Annual, Semiannual )


2014년 8월 6일 수요일

python Quantlib tutorial - Part1

원문 : http://quantlib.referata.com/wiki/Python_QuantLib_tutorial

지난 6월 16일 이직을 하였습니다. 오늘 글의 주제는 이직은 아니고 이직한 곳에서 주로 사용하는 언어에 대한 얘기입니다.

일단 그곳의 환경은 원격지에 서버를 두고 있고 분산 컴퓨팅을 통해서 대량의 계산을 커버하고 있으면 유져들은 주로 excel 환경에서 작업하고 있으면 계산 모듈이 장착된 프로그램은 파이선으로 이루어져 있고 코어 엔진은 C++로 이루어져 있습니다.

주로 사용하는 언어가 C++이어서 객체지향형 프로그래밍에는 익숙하지만 최근의 대세인 python으로 대표되는 스크립트 언어는 ... 개념이 좀 낯설고 잘 적응이 되지 않은 상태입니다.

그래서 파이썬과 주로 사용하던 퀀립을 이어주는 swig에 대해서 공부해보려고 합니다.

금공 공부는 언제 할려는지 ...

ㅎㅎ

일단 당연히 설치부터 설명해보겠습니다.

** windows 환경

일단 c++ 컴파일러를 준비하세요... 음 windows 환경에서 설명을 드릴꺼니까 Visual C++ Express 버젼을 준비하시는게 좋겠네요 .. 그리고 Quantlib 과 Boost를 다운받아서 설치하세요(주제가 주제니 만큼 아마도 이정도 까지는 여러분들도 준비된 상황이라고 생각합니다.) 한가지 걱정은 지금 원문 링크에는 Visual C++ 10은 작동하지 않는다고 햇는데 ... 걱정이네요...

몇일만에 이어서 글을 쓰게 되었습니다. 위에서 걱정한 Visual C++ 10은 실제로 사용이 불가 했습니다. 쓰지말라는걸.. 쓰다 보니까 .. ㅎㅎ

그래서 visual studio 2008 Express 를 설치하고 거기서 제공하는 msvc 9.0 을 사용하였습니다.

아마도 이글을 보시는 분이라면 적어도 QuantLib 과 Boost는 설치 경험이 있으실텐데요. 둘다 다시 설치 하셔야 합니다. QuantLib 이야 방금 설치한 Visual Studio 2008을 이용하면 된다고 하지만 Boost는 컴파일러 버젼을 따로 설정해 주셔야 합니다.

간단히 소개 하자면 일반적으로 Default  Setting을 설치하신다면 boost를 다운받아서 압축을 풀고 그 폴더에 들어가서
$bootstrap
$b2

이렇게 두번 타이핑을 하시면 설치가 끝나게 됩니다. 지금은 컴파일러 버젼을 조정해야 하므로 일단 환경변수에 msvc 9.0이 있는 폴더를 추가 합니다.
저의 경우는 이랬습니다.

C:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin

이런 환경변수를 등록후 다음과 같은 순서로 타이핑합니다.

$bootstrap
$b2 toolset=msvc-9.0

이러면 Visual C++ 9.0버젼으로 빌드를 하신겁니다.

다음으로는 QuantLib을 빌드하시면 됩니다.




2014년 8월 4일 월요일

Celery 설치

우와 앞에꺼에 비하면 정말 쉽다.

pip를 이용시

>>>pip install Celery

easy_install 이용시
>>>easy_install Celery

파일을 다운받아서 설치시
 http://pypi.python.org/pypi/celery/

1
2
3
4
5
6
7
$ tar xvfz celery-0.0.0.tar.gz
$ cd celery-0.0.0
$ python setup.py build
# python setup.py install # as root

개발자 버젼입니다.
깃헙에서 받으세요
1
$ git clone git://github.com/celery/celery.git

잡시다 오늘 허접하지만 많이 나갔네요

pika install

rabbitMQ를 혼자 재설치 해보는데 또하나의 벽이 생겨서 포스팅 하는겁니다.

pika의 설치부분입니다.

pika는 rabbitMQ Library 입니다. 이를 설치하기 위한 방법으로 rabbitMQ는 pip를 이용하여 설치하는것을 권하고 있습니다.

python pakage index라고 알려져 있는 pip를 이용하기 위해서는 설치를 해야 합니다.

이를 설치하기 위해서는 easy_install을 설치하라고 rabbitMQ의 Tutorial에서 링크를 제공합니다.

http://pypi.python.org/pypi/setuptools

위 링크를 따라들어가면 윈도우에서 setuptools를 이용할수 있습니다.

설치방법은 각 os버젼에 따라서 링크를 따라들어가면 알수있는데 기본적으로는  ez_setup.py파일을 다운받아서 설치하는것입니다. 이를 실행하면 파바박 하고 글자들이 막 올라오고 끝이났다고 알려주는데

더이상 무엇을 해야 할지 모르겠습니다.

그래서 다시 튜토리얼에 가서 따라 할려면 .. 에러가 팍팍 ㅜㅜ

가만히 읽어 보니 ez_setup.py를 실행하면 python의 script 폴더에 easy_install이 생겼으니 이를 환경변수에 추가하라고 써있네요 ... 영맹이고 성격이 급한 사람은 찾기 힘들었습니다.(제 얘기네요 ... )

정신을 다잡고 환경변수에 원하는 버젼의 python의 script 폴터를 추가했더니~~~

cmd 에서 easy_install pip 명령이 먹힙니다.

pip가 install 성공했다면 메시지가 뜨면

이번에는

>>> pip install pika

라고 명령합니다..

헐 설치 되었어... 리눅스라고 가장 다르다고 생각했던 부분인 프로그램 설치....윈도우에서도 비슷하게 하는게 가능하네 ... python pakage에 한해서 하는 얘기입니다. 근데 워낙 파이썬이 파생된 프로젝트가 많아서 유용할것 같습니다.

끝~~

Celery 시작하기

분산처리환경, Grid Computing, Message Queue

세가지 개념이 아직 구분이 가질 않습니다. 어린아이가 세상을 다 알지 못하듯이 저 또한 저 세개의 개념을 알지 못하는것이겠습니다.

일단 목표는 정해져 있습니다. 서버에서 마스터 메시지큐 서버를 구축하고 워커를 구축하고 그들의 움직임을 통제하는것입니다.

그것을 위해서 저는 celery를 선택하였습니다. 다른 이유는 없고 python 홈페이지에서 분산컴퓨팅을 위한 패키지라고 설명을 해주었기때문입니다.

일단 설치를 하려고 합니다.

홈페이지 입니다.

http://www.celeryproject.org/

내용을 읽다보니 Broker가 있어야 한다네요 rabbitmq를 설치하라고 합니다.

설치합니다.

http://www.rabbitmq.com/

RabbitMQ를 이용하기 위해서는 erlang을 설치하라고 하네요 .... 올해 초 회사 동료가 공부하자고 해서 책도 사서 읽었던 얼랭이니 ... 설치에는 무리가 없죠 ㅎ

http://www.erlang.org/

역으로 얼랭을 설치하고 rabbitMQ를 설치 후 rabbitMQ에서의 예제인 "Hello world!!" 를 구성합니다.

언어는 파이썬으로 하고

http://www.rabbitmq.com/tutorials/tutorial-one-python.html

rabbitMQ Library인 pika를 이용하기로 합니다.

pika를 설치하는 방법이 여러가지 있다고 하는데 ... pip를 이용한다고 합니다.

예제를 하나 실행하는데도 여정이 깁니다.

https://pypi.python.org/pypi/setuptools

파이썬 링크를 들어가는것 보면 파이썬이 깔려 있어야 하는것 같습니다. 없으시면 파이썬 깔고오세요 ~~~

pip를 깔면 rabbitMQ Tutorial 에서 보이는 pika를 설치할수 있습니다. 현재의 싸이트는 이전 피카버젼을 명시하고 있으므로 피카의 버젼은 그냥 무시하시면 최신버젼이 깔리는것 같습니다.

자 이제 pika를 깔았으면

tutorial을 진행합니다.

내용자체가 tutorial만 보시더라도 알 수 있는 내용이므로 패스

단, 사실 저는 저 tutorial을 성공하기까지 정말 오랜 시간이 걸렸습니다. 아무리 서버를 올려도 에러메시지가 떨어지더라구요... 그래서 에러메시지를 분석한 결과 제가 호스트 네임 부분이 이상하게 들어가고 있다는것을 알았고 그 호스트 네임은 컴퓨터 이름을 이용한다는 사실도 알았습니다. 만일 당신의 컴퓨터이름이 한글이라면 당장 영어로 바꾸세요. 특수문자도 빼시는게 좋겠습니다.

그럼 rabbitMQ를 이용하여 no more faster~~

아 ... Celery 는 가지도 못했네요... 곧가겠죠 ㅎㅎ


2014년 6월 16일 월요일

kooderive 설치와 설정

존경해 마지 않는 Mark S. joshi 아저씨의 최근 역작인 kooderive 분석에 관한 얘기를 쓰겠다.

현재는 kooderive 0.3 버전까지 Release 되어있는 상태이고 이것은

https://www.google.co.kr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&cad=rja&uact=8&ved=0CBsQFjAA&url=http%3A%2F%2Fsourceforge.net%2Fprojects%2Fkooderive%2F&ei=ZgufU7DtNcqF8gXY6ILYAw&usg=AFQjCNFw_G47cWqOgRGjPGEtaCxcYqYNkg&sig2=j1TzzBDwqdBjYlayn6Sgdg&bvm=bv.68911936,d.dGc

에서 확인, 다운로드가 가능하다.

현재 노트북에 있는 그래픽 카드는 GT 540M  이다. 쿠다의 버전은 6.0 toolkit을 쓸것이고 Visual Studio 2012 express for deskTop을 사용할것이다. 무슨 이유인지 Visual Studio 2012는 MS에서 버린 느낌이 들지만 .. joshi 아저씨가 택한 버전이라 .. 따르려고 한다.. 사실 컴터에 2010 버전과 2013 버전이 있지만 ... 둘다 작업을 하다가 실패 했다능...

이전엔 cuda를 깔기가 복잡했던것 같은데 이제는 여기에서 컴터에 맞는 버전을 가져다가 설치를 하면 알아서 visual studio 버전마다 필요한 요소들을 설치해준다. 5.5 버전이 나오기 전에는 좀 복잡하고 설정도 많이 해야 했던거 같은데 ... toolkit이 알아서 해준다. 사실 joshi 아저씨는 toolkit의 버전을 5.5라고 했지만 ... 내가 못찻았다... 그부분은 알아서 누군가가 찾는다면 링크좀 남겨주세요~~

그럼 적당히 준비가 다 된듯 하다.

1. GPU programming이 가능한 그래픽 카드
2. Cuda Toolkit 6.0
3. Visual Studio 2012
그리고
4. kooderive 0.3 release








2014년 6월 1일 일요일

Ten IPython essentials

1. 콘솔에서 IPython 구동하기

IPython이 제대로 설치 되었다면 shell 상에서 IPython 이라는 명령어를 통하여 sheel을 IPython interpreter 처럼 사용할수 있다.

2. IPython을 system shell처럼 사용한다.
IPython shell은 extended shell 로서 pwd, cd, ls 등의 명령어를 이용할 수 있다.
%lsmagic 명령어를 통하여 사용할 수 있는 모든 magic 명령어를 검색할 수 있다.

3. history를 이용하기
IPython은 command history 기능을 제공한다.

4. tap 자동완성
IPython에서는 Tap 키를 이용한 자동완성 기능을 제공한다. Tap키를 이용하여 제공할수 있는 것이 하나라면 자동으로 채워지지만 두개 이상이라면 Tap 키를 이용하여 자동완성을 할수 있는 리스트를 제공한다.

5. %run 명령어
%run 명령어를 통하여 ***.py 형식의 파이썬 스크립트 파일을 실행할수 있다.

6. %timeit
간단한 benchmark 를 위한 magic 명령어이다. 하나의 수행을 하는 경우 경과시간을 표시할수 있다. 하나의 수행을 여러번 반복적으로 수행하는 경우, 각시행의 경과시간과 평균시간을 구할수 있다.

7. %debug
IPython 에는 강력한 디버거가 존재한다. 콘솔상에서 예외처리가 일어나는 경우 어디든지 %debug 명령어를 통하면 모든 지역변수, stack trace back에 접근할수 있고 위아래를 u, d키를 이용하여 이용이 가능하며 q키를 이용하여 종료할수 있다.

8.Pylab
%Pylab magic을 이용하여 공학계산을 포용하고 있는 NumPy 와 matplotlib을 이용할 수 있다.

9. IPython notebook을 이용하기
Notebook은 IPython의 기능을 다행문자편집을 위한 브라우져에서 사용가능하게 한다. 이것은 세련되고 강력한 상호작용과 재생산을 위한 Python을 사용하기 위한 방법이다.

10. Customizing IPython
Python 파일에서 사용자가 선호하는 것을 당신은 저장할수 있다. 이 파일은 IPython profile 이라고 불리운다. 해당파일을 생성하기위해서는 ipython profile create 라고 쓴다. 만약 다른이름의 프로필 파일을 만들고 싶다면 ipython profile create profilename 이라고 쓴다. 그 프로필 파일을 이용하여 ipython을 launch 하고 싶다면 ipython --profile= profilename 이라고 쓴다.


2014년 5월 19일 월요일

python pakage website

1. IPython

http://ipython.org/

2. Numpy 다차원 배열에서의 고성능의 벡터연산을 위한 페키지

http://www.numpy.org/

3. Scipy 진보된 수치적 알고리즘

http://www.scipy.org/

3. Matplotlib

http://matplotlib.org/

4. Matplotlib-basemap mapping tool box for Matplotlib

http://matplotlib.org/basemap/

5. NetworkX

http://networkx.lanl.gov

6. Pandas

http://pandas.pydata.org

7. Python Imaging Library(PIL)

http://pythonware.com/products/pil

8. Cython

http://cython.org

2014년 5월 5일 월요일

IPython 설치하기

IPython 설치하기


IPython을 설치하는 방법은 다양합니다. 그리고  공식문서에서 고급사용자와 개발자를 대상으로 소스에서 수동설치하는 방법을 자세히 다루고 있습니다.

간단히 설치를 원하는 사용자를 위한 설명은 여기에서 하겟습니다. 이것들은 python 2.7을 기반으로 설정이 되어 있습니다. 이것은 notebook 과 과학적인 계산과 데이터 분석에 쓰이는 추가적인 기본 라이브러리모든 종속성을 모두 포함하고 있습니다.

Mac or Windows

1. Anaconda 혹은 무료 버젼인 Enthought Canopy

2. IPython Update 
Anaconda:
conda update conda
conda update ipython
Enthought Canopy:
enpkg ipython

Linux

리눅스에서는 우리가 원하는 모든것은 pakage managers 에 이미 있다.
  1. IPython과 그의 종속적인 것들의 설치:
  • 우분투 혹은 Debian기반의 리눅스 shell:
    sudo apt-get install ipython-notebook
    
  • Fedora 18 :
    sudo yum install python-ipython-notebook
    
  1. 과학적인 계산을 위한 추가 설치:
  • 우분투 혹은 Debian기반의 리눅스 shell:
    sudo apt-get install python-matplotlib python-scipy \
                         python-pandas python-sympy python-nose
    
  • Fedora 18:
    sudo yum install python-matplotlib scipy python-pandas sympy python-nose
    

2014년 4월 24일 목요일

C++ 에서 QuantLib-SWIG 와 Thread-Safe 한 Observer Pattern

원문출처

http://hpcquantlib.wordpress.com/2012/02/27/quantlib-swig-and-a-thread-safe-observer-pattern-in-c/

QuantLib은 사실 Thread-Safe 하지 않습니다. 멀티코어나 병렬환경에서의 성공적인 사용은 여러 프로세스간의  message passing에 의해서 보다는 shared memory 와 multi threading 에 의해서 이루어 집니다. 만약 서로다른 thread 가 서로 다른 object에서 작동을 한다면 QuantLib 또한 Multi threading 환경에서 사용될수 있습니다.(QL_ENABLE_SESSIONS 를 정의 하는 것은 singleton을 thread에 종속적이게 만듭니다.)

만약 당신이 QuantLib을 SWIG를 통하여 Java나 Scala에서 사용한다면 설령 메인 루틴이 싱글스레드 일지라도 QuantLib 루틴은 자동적으로 multi threading 환경에서 실행되어집니다.
JVM의 가비지 컬렉터는 보통 다른 thread에서 돌고 있습니다. 이것은 QuantLib에 구현되어 있는 Observer Pattern 과 결합하여 심각한 문제를 초래 할수 있습니다. 즉, 아래의 간단한 single thread Scala 코드는 멀티코어 컴퓨터에서 짧은 시간에 충돌이 일어날수 있습니다.

import org.quantlib.{Array => QArray, _}
object ObserverTest {
    def main(args: Array[String]) : Unit = {
        System.loadLibrary("QuantLibJNI");
        val aSimpleQuote = new SimpleQuote(0)

        while (true) {
            (0 until 10).foreach(_ => {
                new QuoteHandle(aSimpleQuote)
                aSimpleQuote.setValue(aSimpleQuote.value + 1)
            })
            System.gc
        }
    }
}
같은 객체가 동일한 시점에 aSimpleQuote.setValue 함수에 의해 update 함수가 호출될때 가비지 콜렉터는 observer의 소멸자를 호출합니다.(이 내용에 대한 QuantLib Mailing list는 여기에서 확인 할수 있습니다.). greenfield projects에서 [2]의 저자는 C++에서의 적당한 해답을 제시합니다. 안타깝게도 해당 솔루션은 QuantLib에 적용될 수 없었습니다. 해당 솔루션은 Observer pattern의 interface에 많은 변화를 주어야 하고 obsever pattern의 interface의 변경은 QuantLib library의 아주 많은 변화를 초래하기 때문이었습니다.

가장 중요한 문제는 Observer 가 Destructor가 작용하기 전에 사용불능 상태가 되는것입니다. 이것은 이론적으로 boost::shared_ptr의 새로운 instance 마다 특수한 "삭제자(Deleter)"를 추가하는 것이지만 이것 또한 library의 아주 많은 수정을 초래합니다.

전처리 지시자 BOOST_SP_ENABLE_DEBUG_HOOKS 와 함게 컴파일을 하면 boost library는 boost의 smart pointer의 소멸자가 호출되기전에 callback hook하는 것을 추가하게 된다. 이 hook은 observer의 소멸자가 호출되기전에 observer를 사용할수 없게 하는데 사용한다. 추가적으로 boost::signals2 library [3]은 간단하고 thread-safe한 공지 메커니즘을 제공한다.

원래의 QuantLib의 observer/Observable interface에 맞춰 수정된 thread-safe 한 구현은 여기서 찾을수 있다. 모든 소스파일에  전처리지시자 BOOST_SP_ENABLE_DEBUG_HOOKS를 set 한다. QuantLib project에 observable.hpp 와 observable.cpp 파일을 교체 혹은 추가하고 QuantLib library와 QuantLib-SWIG 모듈을 다시 컴파일 한다.

[1] Simplified Wrapper and Interface Generator, SWIG
[3] Douglas G., Mori Hess F., Boost.Signals2











2014년 4월 22일 화요일

Multi-Threading 과 Quantlib

원문출처

http://hpcquantlib.wordpress.com/2013/07/26/multi-threading-and-quantlib/

QuantLib 자체로는 Thread-Safe 하지 않다. 하나이상의 코어에서 몇개의 독립적인 프로세스를 만드는 것이 표준이다. Ricacardo의 thread-safe 한 singleton 패치는 서로다른 스레드가 명시적으로 객체를 공유하지 않으면 Quantlib을 Multi-threading 응용프로그램에서 사용할수 있습니다. 사실 이 패치는 싱글턴 패턴을 각 스레드 로컬한 싱글턴 패턴으로 바꿔줍니다.

이패치의 사용사례중 하나는 test-suite를 Muliti-threading 환경에서 테스트해보는 것입니다. 예를들어 i7 3.2Ghz 쿼드코어에 하이퍼스레딩 코어 4개를 합한 환경에서 약 8분이 걸리던 작업이 2분정도 걸리게 됩니다.

QuantLib을 Java/Scala/C# or F# 응용프로그램에서 SWIG Layer를 통하여 사용하는 것은 multi-threading 요구사항을 위반하는 것입니다. 왜냐하면 가비지 컬랙터가 다른 스레드에서 실행되고 QuantLib 객체가 서로 다른 쓰레드간에 공유되기 때문이다. 이것은 QuantLib 의 Observer pattern 구현에서 문제를 야기한다 이에 관한 자세한 얘기는 다음에서 다룬다.

boost::signals2 와 Riccardo의 Thread-safe singleton 패치에 기반한 observer pattern의 향상된 구현과 multi-threading test runner는 Github에서 다운 받을수 있다.

Linux/MacOS 환경에서의 사용시

./configure --enable-tss --enable-thread-safe-observer-pattern
thread-safe singleton 과 thread-safe observer pattern을 사용할수 있게 한다.

윈도우 환경에서는 다음에 상응하는 전처리기를 userconfig.hpp 에 명시되어 있습니다.

#define QL_ENABLE_TSS
#define QL_ENABLE_THREAD_SAFE_OBSERVER_PATTERN
boost::shared_ptr의 후크를 변화시키기 위해 다음 파일에서 전처리지시자 BOOST_SP_ENABLE_DEBUG_HOOKS 를 BOOST_SP_ENABLE_DEBUG_HOOKS_2 로 변경합니다.

boost/smart_ptr/detail/sp_counted_impl.hpp
배경 : 원래의 전처리지시자인 BOOST_SP_ENABLE_DEBUG_HOOKS 은 shared_ptr의 메모리 레이아웃을 변경하는 것이 다른 미리 컴파일된 shared_ptr을 사용하는 라이브러리와 문제를 일으킬수 있습니다.

이러한 작업의 이점은 Multi-threading 응용프로그램에서 서로다른 스레드 간에 SWIG/QuantLib 의 객체를 명시적으로 공유하지 않기때문에 Java/Scala/C#/F# and a thread local singleton implementation 을 위한 안정적인 SWIG Interface 입니다.

2014년 4월 17일 목요일

덧셈연산과 곱셈연산의 속도차이

평소에도 궁금하고 프로젝트의 성능을 좌지우지하는 중요한 사항이기때문에
테스트를 해봤습니다.

소스코드는 다음과 같습니다.
<<덧셈연산>>
#include <iostream>
#include <boost/chrono.hpp>

using namespace std;

int main()
{
double a = 1.0;
double b = 1.1;
boost::chrono::high_resolution_clock::time_point start, end;
start = boost::chrono::high_resolution_clock::now();

for(int i=1; i< 5001; i++)
{
a +=b;
}
end  = boost::chrono::high_resolution_clock::now();
cout<<end - start<<endl;

cout<< "value is "<< a << endl;

return 0;
}

<<곱셈연산>>
#include <iostream>
#include <boost/chrono.hpp>

using namespace std;

int main()
{
double a = 1.0;
double b = 1.1;
boost::chrono::high_resolution_clock::time_point start, end;
start = boost::chrono::high_resolution_clock::now();

for(int i=1; i< 5001; i++)
{
a *=b;
}
end  = boost::chrono::high_resolution_clock::now();
cout<<end - start<<endl;

cout<< "value is "<< a << endl;

return 0;
}


제 환경에서는 결과가 다음과 같습니다.
회차   덧셈 곱셈
1 4226 6943
2 4226 7244
3 4528 7245
4 4226 7244
5 4528 7244

덧셈이 빠른가 봅니다.. 이유는 멀까요? 부동소숫점 연산이라 곱셈이 빠를것 같았는데.. 
예상 외입니다.