桜、抹茶、白、日記

名古屋市在住のC++使いのcoderの日記だったもの。

名古屋CV・PRML勉強会(番外編) に参加

d:id:youandi:20110618#p1
CV論文には全く興味はありませんが、Kinect本等の写経での参加もOKという事で行ってきました。

名古屋CV・PRML勉強会(番外編)
http://partake.in/events/6ec42391-80b4-4626-b408-c7782ee86c91

というか、寝坊して1時間遅刻。トータルで4名が参加。

持って行ったり準備したもの

    1. OpenCL入門 - マルチコアCPU・GPUのための並列プログラミング -

      OpenCL入門 - マルチコアCPU・GPUのための並列プログラミング -

    2. Intel® SDK for OpenCL™ Applications | Intel® Software
    3. キネクト ハッカーズマニュアル

      キネクト ハッカーズマニュアル

    4. Xbox 360 Kinect センサー

      Xbox 360 Kinect センサー

    5. Kinect for Windows SDK Beta - Microsoft Research


きっかけは・・・、

iSUS > Intel OpenCL SDK 1.1 の導入
http://www.isus.jp/isus-news/software-news/intel-opencl-sdk-1-1/

この記事の最後の一文・・・、

Intel OpenCL SDK 1.1は、SSE4.1 命令以上を搭載するプロセッサーで実行することができます。拡張版インテル Core マイクロアーキテクチャー・ベースの45nm世代のインテル Core2 Duo プロセッサー以降であればほとんどのシステムで検証できます。ぜひ試してみてください。

えっOpenCLってGPU上でなくても動作するの?って事で試してみたいなと思っていたけど放置したままだったので、今年購入したノートPCがIntel Core-i3を搭載しているし、試してみよう!と思ったのでした。

やったこと

    1. Intel OpenCL SDKのインストール
    2. Kinect for Windows SDKのインストール&サンプルの動作確認
    3. OpenCL入門 - マルチコアCPU・GPUのための並列プログラミング -の写経
    4. GPUなしでも動いたので、OpenCL入門 - マルチコアCPU・GPUのための並列プログラミング -のコードはOpenCLC言語I/Fを使っているのでC++ Wrapper版を書いてみるなど。
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>

#include <fstream>
#include <cstdio>

#ifdef _MSC_VER
#pragma comment( lib, "OpenCL.lib" )
#endif

#define MEM_SIZE            (128)

int _tmain( int argc, _TCHAR* argv[] )
{
    cl_int          ret;
    char            szString[ MEM_SIZE ] = { 0 };
    std::fstream    stream;
    std::string     strSrc;
    const char      szFilename[]    = ".\\hello.cl";
    stream.open( szFilename, std::ios_base::in );
    if ( false == stream.is_open() )
    {
        fprintf( stdout, "Failed to load kernel. : %s\n", szFilename );
        exit( 1 );
    }

    std::string strLine;
    while ( false == std::getline( stream, strLine ).eof() )
    {
        strSrc.append( strLine );
    }
    stream.close();

    cl::Program::Sources    pgSrc;
    pgSrc.push_back( std::make_pair( strSrc.c_str(), strSrc.size() ) );

    try
    {
        VECTOR_CLASS< cl::Platform >    platforms;
        cl::Platform::get( &platforms );

        VECTOR_CLASS< cl::Device >  devices;
        platforms[ 0 ].getDevices( CL_DEVICE_TYPE_DEFAULT, &devices );

        cl::Context context( devices );
        cl::Program program( context, pgSrc );
        ret = program.build( devices );
        if ( CL_SUCCESS != ret )
        {
            fprintf( stderr, "%s(%d) : error(%d) : %s\n", __FILE__, __LINE__, ret, "cl::Program::build" );
            exit( 1 );
        }

        cl::Kernel  kernel( program, "hello" );
        cl::Buffer  memObj( context, CL_MEM_READ_WRITE, MEM_SIZE * sizeof( char ) );
        kernel.setArg( 0, sizeof( cl_mem ), &memObj );
//      kernel.setArg( 0, sizeof( cl_mem ), memObj() ); // これだとエラー。

        cl::CommandQueue    commandQueue( context, devices[ 0 ] );
        ret = commandQueue.enqueueTask( kernel, NULL, NULL );
        if ( CL_SUCCESS != ret )
        {
            fprintf( stderr, "%s(%d) : error(%d) : %s\n", __FILE__, __LINE__, ret, "cl::CommandQueue::enqueueTask" );
            exit( 1 );
        }

        ret = commandQueue.enqueueReadBuffer( memObj, CL_TRUE, 0, MEM_SIZE * sizeof( char ), szString, NULL, NULL );
        if ( CL_SUCCESS != ret )
        {
            fprintf( stderr, "%s(%d) : error(%d) : %s\n", __FILE__, __LINE__, ret, "cl::CommandQueue::enqueueReadBuffer" );
            exit( 1 );
        }

        commandQueue.flush();
        commandQueue.finish();
    }
    catch ( cl::Error& rExp )
    {
        fprintf( stderr, "%s(%d) : error : %s\n", __FILE__, __LINE__, rExp.what() );
    }

    fprintf( stdout, "output : %s\n", szString );

    fprintf( stdout, "\nPress Any Key..." );
    (void)::fgetc( stdin );
    return 0;
}

C++で書くとコード行数が半分になって、エラー処理やハンドル管理もすっきりして良いですね。
後はIntel OpenCL SDKには、OpenCLのオフラインコンパイラも付属するので、より高速な処理が期待できるのですが、作成した実行バイナリをプログラムから読み込んでみたらエラーになって実行できなかった。原因を調べていたら時間切れ。

懇親会

明日はウチの会社営業日なのでパスしました。