2016년 6월 16일 목요일

사람 피 말려 죽이려는 Boost.Log

이 새벽에 포스팅이라뉘...

Local volatility 모형을 작업하기 위해서


c++ 플젝을 생성하고 눈누난나 작업을 시작했다.


당연히 QuantLib과Boost를 임포트 하고 진행..

문제는 로깅에서 나타났다.

부스트에 있는 로깅클래스의 성능이 좋다는 평이 있어서

#include <boost/log/trivial.hpp>

를 하는 순간부터였던것 같다.. 내 삶이 피폐해진것이...

구글링 구글링~~~

자주 목격한 boost.Log와 ThirdParty간의 충돌문제..

해결책 1.
http://www.boost.org/doc/libs/1_56_0/libs/log/doc/html/log/rationale/namespace_mangling.html

아무리바도 먼말인지 모르겠어서 몇번을 읽어 보니

BOOST_LOG_DYN_LINK 또는 BOOST_LOG_ALL_LINK를 정의해봐라 이얘긴데

이얘기가

boost_root/boost/config/user.hpp

파일 내부에

#define BOOST_LOG_DYN_LINK
또는
#define BOOST_LOG_ALL_LINK

문구를 집어 넣으라는 얘기 였음. 이걸 알아내는데 까지 2주 걸린듯... ㅠㅠ

해봤지.. 몇번이나..버전문제인가 해서 새버젼 받아서도 해봄. 부스트 정말 20번은 빌드 해봤음....지금 포스팅을 하는 오늘도 열번은 족히했다..ㅠㅠ

일단 저건 해결책 아녔다는것도 알아차리는데 한참걸렸다.

해결책 2.
 https://github.com/boostorg/log/issues/28

 저 글을 읽었을때 깜놀...엇 나 windows10인데...나랑 에러메시지도 같애.. 헐퀴 머지

가만히 읽어 보니 부스트 빌드할때 대상플랫폼을 지정해줘야 한다는 얘기.


마찬가지로 비스타 버전, 윈7버전, 윈8 버전 윈10버전 다 빌드 해봄, 위에 내용하고 엮어서 BOOST_LOG_DYN_LINK이것도 넣고 해보고 빼고 해보고 새로 받아서 다시 해보고 이 내용을 알고난후 빌드 빌드 빌드 빌드 ,,,삭제..빌드 반복 출근..퇴근...빌드

 해결책 3.
딱 오늘 새벽 2시가 넘었을때 그래 인제 포기 하자 포기!!!!
라고 생각하고 마지막으로 튜토리얼은 돌아가는지 확인 하려고 튜토리얼 만듬. 돌림. 돌아감. 머지.. 왜 돌아가지? 그럼 위의 두가지 문제는 절대 아니겠네..define 할것을 안했거나 대상플랫폼이 잘못 지정되면 돌아갈리가 만무한데..

혹시나 해서 퀀립 임포트 함..
돌아감..

동공지진..

이전에 만들었던 플젝과 비교했을때 차이는 하나였음. 기존 플젝은 local vol작업을 위한 플젝이라서 이것저거 하다가 로그가 필요해서 include 한것이고 이번건 순수 Boost.Log 튜토리얼이라서 가장 처음에
#include <boost/log/trivial.hpp>

하고있다.... 헐퀴...인클루드 순서였음.

나랑 비슷한분 발견...

http://www.gpgstudy.com/forum/viewtopic.php?p=39360

아ㅡㅇ민ㅇ러ㅐ쟈ㅗㄷ라넝퓨ㅑ며ㅗㄴㄹ어리쟏렂ㄷ러ㅣ파타처ㅗㅍㅈ

그랬음...c++의 경우 몇몇의 파일들은 인클루드 순서가 있었다능...
windows 응용프로그램 만들때 몇번 겪어본건데...흐앙

마지막 링크의 문답중에서 이런 문구가 가슴을 후벼판다..

실용주의 프로그래머의 표현을 빌리자면 "우연에 맡기는 컴파일" 이라고 볼 수 있겠군요.

나는 우연에 맡겼던것이야~~~

멀고도 험한 인생길 오늘은 다리 뻗고 자겠군 크하하하하하하핳


오늘의 나의 삽질기 기록 끝~~~~!~!~!~!

2016년 5월 15일 일요일

vim으로 IDE같은 기분 내기~~

VIM으로 IDE같은 기분내기

YouCompleteMe & NERDTree

일을 하다보면 텍스트 에디팅과 파일관리등의 업무를 하다보면 키보드와 마우스를 번갈아 쓰게되고 업무의 집중력도 저하되고 일의효율도 떨어지는 느낌을 지울수 없다.

command 창에서 파일 오퍼레이팅을 하고 코딩은 Pycharm 혹은 Visual Studio에서 작업을 하다보면 생기는 자연스러운 어쩌면 부자연스러운 일이다.

그러다가 알게된 vi란 녀석은 그동안 참 계륵이었다. Command창에서 파일오퍼레이팅을 하고 vi로 바로 텍스트 에디팅을 할수 있어서 참 좋다고 생각했다. 하지만 문제는 IDE에 비해서 코딩을 하는데 너무 불편하다. 자동완성, 파일익스플로러 등의 기능이 지원되지 않으니...

어느날 검색중에 발견한 YouCompleMe 와 NERDTree란 두 녀석이다.

1. 일단 가장 먼저 소개하고 싶은것은 vimawesome(빔간지...정도인가)이다. vim에서 사용할수 있는Plugin들의 리스트와 설명들을 모아놓은 사이트이다.
vimawesome


2.  IDE의 자동완성, GoTo 기능이 부럽다면 YouCompleteMe가 꼭 필요하다.
YouCompleteMe

3. File Navigation 기능이 필요하다면 NERDTree가 최고다.
NERDTree

위의 내용들은 사실 *NIX 에서 개발하는 개발자분들에게는 위 내용은 그냥 기본일 수도 있다.

하지만 Windows에서라면 전혀 다른 애기가 될수도 있다. 단순히
apt-get install package name

이렇게 끝나지 않아서 문제다 ㅠㅠ

설치방법

설치방법은 홈페이지에 잘나와있다. 이걸 쓸려고 포스팅중은 아니다. 핵심 내용은 아래에 있다.

지금부터 삽질한 썰을 풀어보겠다.

1. %USERPROFILE%, %HOME% 이게 멀까?

YouCompleteMe를 설치하는 메뉴얼을 읽어보면 Vundle을 설치하라고 한다.
Vundle을 설치하다보면 %USERPROFILE%, %HOME% 이게 멀까? 하는 생각이든다.

vim 의 path관련 변수이다.
%USERPROFILE% : 보통여기다 C:\Users\user ...사람들 pc마다 다를수 있다. 궁금하면

Command창에서 쳐보면 된다.
>%USERPROFILE%

%HOME% : vim 을 설치하면서 path에 추가 할까요? 할때 등록이 되는 변수다. 이것도 마찬가지로 궁금하면 커멘드창에 쳐보면 된다.

먼기 기본도 몰랐던 느낌...ㅠㅠ

2. vim이 python을 지원하지 않는다. 

이거는 정말 큰 문제라고 생각된거 중 하나다.
검사하는 방법은
vim실행후
:echo has('python')
이라는 명령어를 실행하면
지원하지 않는 경우 '0', 지원하는 경우 '1' 이라는 값으로 리턴된다.

이문제는 정말 어렵게 해결했다. 아래 링크를 타고 가면 할수 있다.
https://www.google.co.kr/url?sa=t&rct=j&q=&esrc=s&source=web&cd=2&ved=0ahUKEwiYn4eJr9zMAhVBuI8KHWP2B5EQFggoMAE&url=http%3A%2F%2Fvim.wikia.com%2Fwiki%2FBuild_Python-enabled_Vim_on_Windows_with_MinGW&usg=AFQjCNHLoZak-u7wNCREzpX13XMEyOoTiQ&sig2=Un70EqzMmklLPMIuZP5DSw&bvm=bv.122129774,d.c2I&cad=rjt

하지만 설치 메뉴얼을 천천히 읽었으면 이런 문구를 읽었을텐데...

We recommend using a 64-bit client. Daily updated copies of 32-bit and 64-bit Vim with Python 2 and Python 3 support are available.

3. python27.dll, python34.dll 니네 어디 갔냐?

파이썬 설치하면 자동으로 각각의 dll이 시스템폴더에 잘 들어 간다. 삽질을 하다보니 꼬여서 python27.dll이 없어졌다. 일반 설치파일을 이용해서 Uninstall 후 다시 install을 하였지만 인스톨 자체가 꼬였다. 그래서 Anaconda를 깔아 버렸다. 이건 참 안정적으로 잘깔리고 conda하는 패키지 업데이트가 안정적인 업데이트를 지원한다. pip랑 비슷한 역할을 담당하고 있다.
하지만 pip의 특성상 윈도우 패키지를 딱 맞춰주지 않기 때문에 conda가 참 좋은 녀석이라고 생각된다.



인제 잘써야지 마지막으로 vim +  YouCompleteMe + NERDTree 설치 인증샷이나 하나 남겨야지~~~~

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등을 사용할수 있으니 편한것을 설치하고 설정하면 된다.

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