bionote.net


Boost.Python을 이용한 python extension


파이썬은 단시간에 손쉽게 코드를 완성할 수 있어서, 새로운 아이디어를 구현해서 테스트해보기에 적합한 언어이다. 아이디어를 구현하는 초기에는 파이썬을 이용한 코딩이 많은 시간을 절약시켜 준다. 하지만 대용량의 데이터를 이용한 프로그램 검증이나 최적 파라미터를 찾는 등의 작업을 하기에는, 프로그램 수행속도가 느리다는 점에서 손해를 감수해야한다.

이런 문제를 해결할 수 있도록 low-level 언어인 C/C++를 이용해서 파이썬 인터페이스를 확장할 수 있다. Boost.Python은 이 확장 작업을 손쉽게 할 수 있도록 도와주는 라이브러리이다.

이후에 다시 참고하기 편하도록, 여기(http://radiohead.springnote.com/pages/712895)에서 정리한 내용을 다시 정리해본다.

  1. Boost.Python 설치
    우분투에서 다음 명령어를 이용해서 Boost.Python을 설치할 수 있다.
    $ apt-get install libboost-python-dev libboost-python1.34.1

    또는, http://www.boost.org/에서 Boost Jam과 Boost library를 다운로드 받은 후에 bjam을 이용해서 설치하는 방법이 있다.
    $ bjam --prefix=$HOME --with-python install
    --with-python 옵션을 같이 주면 Boost.Python이 설치된다. configure 명령어를 사용할 때와 마찬가지로 --prefix를 사용해서 설치위치를 지정할 수 있다.

  2. 간단한 예제 모듈
    간단한 문자열을 출력하는 예제 코드이다.
    // greet.cpp
    //
    #include <stdexcept>

    char const* greet(unsigned x) {
      static char const* const msgs[] = { "hello", "Boost.Python", "world!" };
      if (x > 2)
        throw std::range_error("greet: index out of range");
      return msgs[x];
    }

    #include <boost/python.hpp>
                       
    using namespace boost::python;
                       
    BOOST_PYTHON_MODULE(hello) {
      def("greet", greet, "return one of 3 parts of a greeting");
    }

    위의 C++ 코드를 파이썬 모듈로 작성하기 위한 setup.py를 아래와 같이 만든다.
    from distutils.core import setup, Extension

    module1 = Extension('hello',
                         include_dirs = ['/usr/include/boost'],
                         libraries = ['boost_python'],
                         library_dirs = ['/usr/lib'],
                         sources = ['greet.cpp'])

    setup (name = 'hello',
           version = '1.0',
           description = 'This is a demo package',
           ext_modules = [module1])

  3. 파이썬 인터프리터에서 예제 모듈 사용하기
    아래 명령어로 예제 코드를 빌드한다.
    python setup.py build


    빌드가 완료되면 현재 디렉토리 아래에 build/lib.linux-XXX에 hello.so가 생긴다. 이제 hello 모듈을 import해서 실행시켜 보자.
    >>> import sys
    >>> sys.path.append('build/lib.linux-XXX')
    >>> import hello
    >>> for x in range(3): print hello.greet(x)
    hello
    Boost.Python
    world!
자세한 설명과 튜토리얼은 이곳(http://www.boost.org/doc/libs/1_37_0/libs/python/doc/index.html)으로 가면 얻을 수 있다.

Boost.Python으로 alignment를 구현해보았는데 python에서 C++로 대체된 부분에 대해서 수행시간이 획기적으로 개선되었다. 특히 다른 방법들과 비교했을 때, Boost.Python은 파이썬과 비슷한 스타일로 코딩을 할 수 있다는 점이 마음에 든다.

python profiler를 이용해서 파이썬 코드의 수행시간을 분석하고, 많은 시간이 소용되는 부분에 Boost.Python을 적용하면 효과적으로 코드를 최적화할 수 있을 것이다.
2008/12/11 20:22 2008/12/11 20:22
top

 

MATLAB을 스크립트처럼 사용하기


MATLAB은 복잡한 행렬계산을 빠르고 단순하게 처리하는데 유용한 툴이다. 하지만 10줄도 안되는 단순한 MATLAB 스크립트를 실행하기 위해서 X-window를 사용해서 MATLAB 창을 띄우는 일은 귀찮은 일이다. 특히 여러개의 클러스터 노드를 사용해서 작업을 하는 경우에는 더욱 그러하다. 이 경우에 아래의 옵션을 사용하면 파이썬이나 펄 스크립트처럼 MATLAB 코드를 실행할 수 있다.

-nodesktop: MATLAB 데스크탑 창이 실행되지 않고 VT100 터미날 모드에서 실행되도록 해준다.
-nosplash: 처음에 잠깐 보였다가 사라지는 로고창이 실행되지 않도록 한다.
-r [MATLAB_command]: MATLAB이 시작되자마자 주어진 MATLAB_command를 실행한다.

예를들어 foo.m 이라는 스크립트를 실행하고 싶다면 다음과 같이 하면 된다.

]$ matlab -nodesktop -nosplash -r "foo();exit;"

2007/03/09 11:24 2007/03/09 11:24
top

TAG
 

Subversion 저장소 구조화하기


Subversion은 아주 효과적인 버전관리를 수행해주는 프로그램으로 널리 사용되고 있다. 하지만 저장소를 효과적으로 구조화하지 않으면 시간이 지남에 따라 해결하기 힘든 충돌이 발생하거나 팀원들간의 (또는 서브 프로젝트) 코드 공유를 번거롭게 만드는 일이 발생할 수도 있다. 따라서 저장소 구조화를 위한 가이드라인이 필요하다.

프로젝트 projectA에 대한 subversion 저장소는 기본적으로 다음과 같은 구조를 갖는다.

svn_repos
   /projectA
      /trunk
      /branches
         /RB-[RELEASE_NUMBER]
         /BUG-[BUG_TRACK_NUMBER]
         /TRY-[ABBREVIATION]-[EXPLANATION]
      /tags
         /REL-[RELEASE_NUMBER]
         /PRE-[BUG_TRACK_NUMBER]
         /POST-[BUG_TRACK_NUMBER]
         /EXP-[EXPERIMENT_NUMBER]

각 디렉토리의 역할은 다음과 같다.
  • trunk는 프로젝트가 주로 진행되는 디렉토리이다.
  • branches는 릴리즈 준비, 버그 교정, 새로운 시도 등의 이유로 trunk와 병렬로 프로젝트를 진행하게 되는 디렉토리이다. branches 아래 위치하는 디렉토리명이 가지를 생성한 이유를 말해줄 수 있다면 더욱 좋겠다. RB는 릴리즈를 준비하는 가지이다. BUG는 버그교정 작업을 진행하는 가지이다. TRY는 새로운 아이디어나 기능 등을 실험할 때 사용할 수 있는 가지이다.
  • tags는 릴리즈되는 버전들을 별도로 관리하는 디렉토리이다. REL는 릴리즈되는 프로그램을 위한 태그이고, PRE와 POST는 각각 버그가 교정되기 이전과 이후 버전을 표시해주는 태그이다. EXP는 실험에 사용된 코드를 표시하기 위한 태그이다.

REFERENCE
  • Mike Mason, (류광 역), 서브버전을 이용한 실용적인 버전 관리, 정보문화사, 2006.
2006/10/03 02:10 2006/10/03 02:10
top

 

Python으로 데몬(daemon) 프로세스 생성하기


데몬 프로세스는 백그라운드 모드로 실행되면서 사용자의 요청이 있을 때마다 적절한 작업을 수행해주는 프로세스를 말한다. 데몬이 단순한 백그라운드 프로세스와 구분되는 것이 데몬의 경우에는 부모 프로세스가 1번 init으로 세팅되어 있고 터미널을 가지고 있지 않다는 점이다. 따라서 다음의 과정을 따르면 POSIX 인터페이스를 이용해서 데몬을 작성할 수 있다 [1].
  1. fork()로 자식프로세스를 생성하고 부모 프로세스를 종료한다.
  2. 자식 프로세스에서 새로운 세션을 생성한다.
파이썬 코드로 다음과 같이 쓸 수 있다 [2].

def Daemon():
  try:
       pid = os.fork()
       if pid > 0: sys.exit(0)
  except OSError:
       print >>sys.stderr, "fork() failed"
       sys.exit(1)
  os.setsid()
  os.umask(0)
  try:
      pid = os.fork()
      if pid > 0: sys.exit(0)
  except OSError:
      print >>sys.stderr, "second fork failed"
      sys.exit(1)

  # REDIRECT STDOUT/STDERR TO OUT/ERR FILES #
  out_log = file("log/out",'a+')
  err_log = file("log/error",'a+',0)
  os.dup2(out_log.fileno(), sys.stdout.fileno())
  os.dup2(err_log.fileno(), sys.stderr.fileno())

  # DO WHAT YOU WANT HERE #

이 코드에서 첫번째 fork()는 부모 프로세스를 죽이고 새로운 세션을 생성한다. 두번째 fork()는 새로운 세션에서 데몬이 세션리더가 되는 것을 피하기 위해서 사용된다. os.setsid()에 의해서 데몬은 세션리더가 되는데, 세션리더가 터미널의 파일 기술자(file descriptor)를 열게 된다면 그 열린 터미널이 현재 세션의 터미널이 된다. 터미널을 가지면 데몬이 아니기 때문에 이런 경우를 안전하게 피하기 위해서 두번째 fork()를 사용해서 데몬 프로세스가 세션리더가 되는 것을 방지한다 [2].

References
[1] C로 간단한 데몬(daemon)제작하기, http://data.oss.or.kr/sw/view.html?sort=&num=649&page=1
[2] Fork a daemon process on Unix, http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/66012
2006/07/18 09:54 2006/07/18 09:54
top

 

큐잉(queueing) 기능의 구현


단백질의 구조를 자동으로 예측해주는 서버를 구축해서 시험 가동하던 중 한가지 문제가 생겼다. 한꺼번에 다수의 쿼리가 수행될 경우에 전체 시스템이 느려지는 현상이 발생한다. 따라서 큐잉 기능을 추가할 필요가 생겼다.

요구사항은 다음과 같다.
  1. 다수의 작업이 입력되더라도 가장 먼저 입력된 하나의 작업만을 프로세서에서 처리되도록 한다.
  2. 현재 작업큐의 상태를 모니터링할 수 있어야 한다. 이때 보여주는 정보는 작업명, 인덱스, 입력시간을 반드시 포함한다.
  3. 작업이 큐에 대기하는 시간을 최소한이 되도록 효율적이어야 한다.

조사해 본 바로는 UNIX의 named pipe를 이용하면 큐잉 기능을 구현하는 것이 가장 간편해 보였다. 실제로 병철 선배가 같은 방식으로 큐잉을 구현해봤는데 간단하고 지금도 정상적으로 작동하고 있다고 한다. 파이썬에서도 mkfifo() 함수를 제공하고 있어서 일반파일처럼 read(), write() 함수로 다룰 수 있다 [조성준, [예제] FiFO(Named Pipe), http://www.openphp.com].

사용자로부터 입력을 받으면 1) 웹프로그램은 작업큐에 작업을 입력한다. 각각의 정보를 '\0'로 구분해서 하나의 작업이 하나의 라인에 저장되도록 한다. 2) 서버 프로그램은 데몬처럼 돌면서 FIFO에 read()를 수행하고 read()가 성공하면 실제 구조 예측 프로그램에 의해서 작업이 수행되도록 한다. 3) 구조 예측 작업이 끝나면 다시 read()를 시도하는 일부터 루프를 돈다.

2006/07/17 00:28 2006/07/17 00:28
top

 

[Linux] 똑똑하게 텍스트 파일을 합쳐주는 join 명령어


join 명령어는 예전에 올렸던 paste 명령어와 유사한 기능을 하지만 조금 똑똑하게(?) 일을 해준다. 두 파일을 합칠 때 공통되는 컬럼을 한번씩만 출력되도록 합쳐주기 때문에 RDB처럼 써먹을 수 있다. 단, 합치려는 파일들이 미리 동일한 순서로 정렬되어 있어야한다는 점을 주의하여야 하겠다. 사용법은 다음과 같다.

]$ cat salary.txt
Kim 100
Lee 80
Jeong 80
]$ cat skill.txt
Kim CPP
Lee PHP
Jeong Java
]$ join salary.txt skill.txt
Kim 100 CPP
Lee 80 PHP
Jeong 80 Java

"-o" 옵션을 사용하면 출력포맷을 지정할 수 있다. 출력포맷은 컴마(,)로 구분해서 "FILENUM.FIELD" 형식으로 입력해주면 된다. 예를 들어 위의 예제에서 salary 값과 skill만을 출력하고 싶다면 아래와 같이 하면 된다.

]$ join salary.txt skill.txt -o 1.2,2.2
100 CPP
80 PHP
80 Java

"-o 2.2,1.2" 옵션을 주면 순서를 바꾸는 것도 당연히 가능하다.

2006/05/18 03:14 2006/05/18 03:14
top

 

기숙사 컴퓨터 셋팅


기숙사 컴을 새로이 셋팅했다. 기존에는 하드에 윈도우즈 XP와 우분투 리눅스를 설치해서 사용했는데, 사실상 리눅스의 이용률이 높지도 않았고 하드의 데이터 파티션도 모자라서 윈도우즈 XP만 설치해서 사용하기로 했다. 새 시스템의 설치과정은 다음과 같다.

  1. 파티션 설정
    C: 5GB. OS
    D: 2GB. Swap과 임시파일
    E: 20GB. 어플리케이션
    F: ramains. 사용자 프로파일(Documents and settings)을 비롯한 데이터

  2. 자동응답파일을 이용한 윈도우즈 설치
    윈도우즈 NT계열은 윈도우즈 설치과정에서 해야되는 일들을 자동화해주는 역할을 하는 자동응답파일을 설정할 수 있다. 자동응답파일의 생성은 이곳을 참고한다. [1] 나는 unattend.txt에 아래 내용을 추가해서 자동으로 Documents and settings와 Program Files가 변경되도록 설정하였다.
    [Unattended]
    ProgramFilesDir=e:\Application
    CommonProgramFilesDir=e:\Application\CommonFiles
    [GuiUnattended]
    ProfilesDir=f:\Profile
    하지만 실제로 위의 내용처럼 설치되기 위해서는 하드디스크가 미리 파티셔닝되고 포맷되어 있어야한다. 설치는 CD를 CD-ROM에 넣고서 CD-ROM  드라이브에서 \i386\winnt32.exe /unattend:unattend.txt 를 실해하면 된다.

  3. 드라이버 업데이트
    윈도우즈 설치가 완료 되었으면 하드웨어와 관련된 드라이버들을 업데이트 해준다. 윈도우즈에서 기본으로 이더넷 카드 드라이버가 없을 수 있으니 미리 드라이버들을 다운 받아서 CD로 구워놓으면 편하다. 내가 한 드라이버 업데이트는 다음과 같다.
    메인보드 BIOS
    메인보드 LAN 카드
    메인보드 칩셋 INF
    메인보드 칩셋 IAA
    그래픽 카드
    LCD 모니터
    사운드 카드
    PS interface

  4. 윈도우즈 업데이트
    디바이스 드라이버가 모두 설치되었으면 윈도우즈 업데이트를 한다. 이 부분도 미리 업데이트 파일들을 다운로드 받아놓으면 편리하게 할 수 있다. 요즘은 인터넷만 연결되면 바로 웜에 감염되서 업데이트 하다가 짜증나는 경우가 많다.

  5. 필수 유틸리티 설치
    컴퓨터 사용에 반드시 필요한 유틸리티를 설치한다. (그전에 윈도우즈 업데이트는 반드시 하자!) 내가 설치한 유틸리티는 다음과 같다.
    Firefox
    빵집
    FileZilla
    KMPlayer
    바이러스 체이서
    꿀뷰
    XnView
    KeyTweak [2]
    SlickRun
    foobar
    Total commander
    알콜
    CCleaner

  6. 응용 프로그램 설치
    이제 할 일들은 다 한 것 같다. 쓰고 싶은 응용 프로그램들을 설치하면서 놀아보자!
내 컴이 다른 컴들과 다른 점이 Documents and settings와 program files를 다른 드라이브로 바인딩해서 사용한다는 점인데, (이렇게 쓰는 파워 유저가 적지는 않을 듯 싶다.) 가끔 이 점 때문에 응용프로그램 사용에 제약을 받는 경우가 있다. 그런 경우는 막기 위해서 기본 윈도우즈 환경과 동일한 환경을 만들어준다. 리눅스에서 심볼릭 링크를 걸듯이 c:\Program Files와 c:\Documents and settings를 각각 e:\Application과 f:\Profile로 링크를 생성해준다. 이 작업은 Junction이라는 프로그램을 이용하면 간단하게 처리 가능하다. [3]

References
[1] http://qaos.com/sections.php?op=viewarticle&artid=218
[2] http://blna999.ivyro.net/tt/entry/KeyTweak-Keyboard-remapper
[3] http://blna999.ivyro.net/tt/entry/Windows-Junction

2006/05/04 00:19 2006/05/04 00:19
top

 

[Linux] 다른 파일에 저장된 연관된 데이타를 합쳐서 출력하기, paste 명령어


paste 명령어는 다른 파일에 저장된 연관된 데이타를 하나로 합쳐서 출력해주는 프로그램이다. 사용법은 다음과 같다.
]$ cat a
personA
personB
personC
]$ cat b
Seoul
Cheju
Boston
]$ cat c
Korea
Korea
USA
]$ paste a b c
personA   Seoul    Korea
personB   Cheju    Korea
personC   Daejon    USA

파일 a, b, c에는 라인별로 일치하는 데이타가 저장되어 있다. paste를 이용하면 일치하는 라인별로 TAB으로 연결되서 결과가 출력된다. '-d ' 옵션을 이용하면 TAB 대신 다른 문자를 delimiter로 이용할 수 있고, '-s' 옵션은 병합방식을 parallel에서 serial로 변경할 수 있다.

2006/04/27 06:22 2006/04/27 06:22
top

 

[Linux] 일괄적으로 문자를 변경하거나 삭제할 때 유용한, tr 명령어


tr은 standard input으로 입력된 문자들을 규칙에 따라서 변환하거나 삭제한 결과를 standard output으로 출력해주는 명령어이다. shell 상에서 간단히 텍스트 파일의 형식을 맞춰줄 필요가 있을 때 유용하게 사용할 수 있다.
예를 들어 file의 모든 대문자를 소문자로 변경하고 싶으면,
[CODE]]$ cat file |tr "[A-Z]" "[a-z]"[/CODE]
와 같이 하면된다.

2006/04/03 16:40 2006/04/03 16:40
top

 

[Linux] screen 사용법


screen은 하나의 물리적인 터미널을 통해서 다수의 가상터미널을 관리하게 해주는 프로그램이다. 각각의 터미널 세션은 독립적이기 때문에 세션을 사용하다가 detach 시켜두면 나중에 접속해서 resume 시켜서 같은 환경으로 사용이 가능하다. 사용법은 간단히 다음과 같다.
1. 새 세션을 생성한다.
]$ screen -S sessioname
2. 사용하던 세션을 detach시키기 위해서는 Ctrl + a, d 를 사용한다.
3. 현재 생성된 세션목록을 본다.
]$ screen -ls
4. detach된 세션을 다시 보기 위해서는 다음 명령어를 사용하면된다.
]$ screen -r sessioname
2006/02/13 15:14 2006/02/13 15:14
top