QA@IT
«質問へ戻る

コメント修正

0
本文
 		 */
 		__kernel void Example( __global float out[] )
 		{ 
-			/* 大域の1次元目の識別子に従って配列を-1で埋める */
+			/* 広域の1次元目の識別子に従って配列を-1で埋める */
 			out[get_global_id( 0 )] = -1;
 		}
 	));
  * End
  * -------------------------------------------------------
  * OpenCLがGPUで処理するかCPUで処理しているかは、
- * 今回OpenCLの各ClassのgetDefault()にまかせているため不定。
+ * 今回OpenCLの各Classが持つgetDefault()にまかせているため不定。
  */
 signed main( signed, const char*[] )
 try
 	cl::make_kernel<cl::Buffer>
 		example( program, "Example" );
 
-	// OpenCL側の大域での反復数
+	// OpenCL側の広域並列数
 	cl::EnqueueArgs
 		enqueue_args = cl::NDRange( length );
 

OpenCLのcl::copyが上手く動かない

 OpenCLの動作確認用に下記のCodeを作成しました。
下記のCodeのうち#if 0を書き換えて、enqueueReadBuffer()を使わず、
cl::copy()を使うようにすると正しくOpenCL側の処理結果を取得できません。
何故でしょうか?( 結果がおかしいだけで例外やErrorは発生していません )

 cl::copyの中では、clEnqueueMapBufferとclEnqueueUnmapMemObjectが
使われているのですが、これらの関数を正しく呼び出せる条件をわたしが
間違えているようにも思います。

 今回使用した環境ですが、下記になります。

OS:                 Fedora 17
OpenCL Platform:    AMD Accelerated Parallel Processing
CPU:                AMD A8-3850 APU with Radeon(tm) HD Graphics
主記憶容量:            15.1GB

どなたかご教示お願いいたします。

// Errorは全て例外処理で受け取る
#define __CL_ENABLE_EXCEPTIONS

#if defined( __APPLE__) || defined(__MACOSX )
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include <cstdio>
#include <cstdlib>
#include <iostream>

/**
 * Error codeから処理失敗時の通知を作成する
 */
inline const char *LookupErrorMessageWhere( cl_int code )
{
    //省略
}

#define QUOTE(string) #string
const std::string
    example_string =
    QUOTE
    ((
        /**
         * 単に入力した配列に-1を書き込むだけのOpenCL関数
         */
        __kernel void Example( __global float out[] )
        { 
            /* 広域の1次元目の識別子に従って配列を-1で埋める */
            out[get_global_id( 0 )] = -1;
        }
    ));

/**
 * OpenCLの動作を確認するためだけのProgram
 * 本来であれば、標準出力に下記の様な文字列を吐き出す
 *
 * -------------------------------------------------------
 * Quit Order
 * Result: -1 
 * Result: -1 
 * Result: -1 
 * Result: -1 
 *     ・
 *     ・
 *     ・
 * End
 * -------------------------------------------------------
 * OpenCLがGPUで処理するかCPUで処理しているかは、
 * 今回OpenCLの各Classが持つgetDefault()にまかせているため不定。
 */
signed main( signed, const char*[] )
try
{
    // OpenCL側にShader実行形式を作成する
    cl::Program
        program = cl::Program( std::string( example_string.begin() + 1, example_string.end() - 2 ) );

    program.build();


    // OpenCL側に結果を書き込む領域を作成する
    const size_t
        length = 0x10;
    cl::Buffer
        array( CL_MEM_READ_ONLY, length * sizeof( float ) );


    // OpenCL側のExample関数を作成する 
    cl::make_kernel<cl::Buffer>
        example( program, "Example" );

    // OpenCL側の広域並列数
    cl::EnqueueArgs
        enqueue_args = cl::NDRange( length );

    // Example関数を実行( 呼び出し指示を命令Queueへ追加 )
    for( signed i = 0; i < 0x10; ++i )
    {
        example( enqueue_args, array );
    }

    std::cerr << "Quit Order" << std::endl;

    // OpenCLの処理結果を受け取る領域を作り結果を書き込む
    std::vector<float>
        buffer;

    buffer.resize( length );
#if 0
    // こちらを使うとbufferの書き換えが一切おこらず上手く行かない
    cl::copy( array, buffer.begin(), buffer.end() );
#else
    // こちらを使うと想定通りbufferが-1で埋め尽くされる
    cl::enqueueReadBuffer
    (
     array,
     CL_TRUE,
     0,
     length * sizeof( float ),
     &buffer[0]
    );
#endif

    // 処理結果の確認
    for( size_t i = 0; i < length; ++i )
    {
        std::cerr << "Result: " << buffer[i] << std::endl;
    }

    std::cerr << "End" << std::endl;

    return EXIT_SUCCESS;
}
catch( const cl::Error &error )
{
    std::cerr 
        << "ERROR: "
        << error.what()
        << "("
        << LookupErrorMessageWhere( error.err() )
        << ")"
        << std::endl;

    return EXIT_FAILURE;
}
 OpenCLの動作確認用に下記のCodeを作成しました。
下記のCodeのうち#if 0を書き換えて、enqueueReadBuffer()を使わず、
cl::copy()を使うようにすると正しくOpenCL側の処理結果を取得できません。
何故でしょうか?( 結果がおかしいだけで例外やErrorは発生していません )

 cl::copyの中では、clEnqueueMapBufferとclEnqueueUnmapMemObjectが
使われているのですが、これらの関数を正しく呼び出せる条件をわたしが
間違えているようにも思います。

 今回使用した環境ですが、下記になります。
```
OS:					Fedora 17
OpenCL Platform:	AMD Accelerated Parallel Processing
CPU:				AMD A8-3850 APU with Radeon(tm) HD Graphics
主記憶容量:			15.1GB
```

どなたかご教示お願いいたします。
```cpp
// Errorは全て例外処理で受け取る
#define __CL_ENABLE_EXCEPTIONS

#if defined( __APPLE__) || defined(__MACOSX )
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include <cstdio>
#include <cstdlib>
#include <iostream>

/**
 * Error codeから処理失敗時の通知を作成する
 */
inline const char *LookupErrorMessageWhere( cl_int code )
{
	//省略
}

#define QUOTE(string) #string
const std::string
	example_string =
	QUOTE
	((
	  	/**
		 * 単に入力した配列に-1を書き込むだけのOpenCL関数
		 */
		__kernel void Example( __global float out[] )
		{ 
			/* 広域の1次元目の識別子に従って配列を-1で埋める */
			out[get_global_id( 0 )] = -1;
		}
	));

/**
 * OpenCLの動作を確認するためだけのProgram
 * 本来であれば、標準出力に下記の様な文字列を吐き出す
 *
 * -------------------------------------------------------
 * Quit Order
 * Result: -1 
 * Result: -1 
 * Result: -1 
 * Result: -1 
 *     ・
 *     ・
 *     ・
 * End
 * -------------------------------------------------------
 * OpenCLがGPUで処理するかCPUで処理しているかは、
 * 今回OpenCLの各Classが持つgetDefault()にまかせているため不定。
 */
signed main( signed, const char*[] )
try
{
	// OpenCL側にShader実行形式を作成する
	cl::Program
		program = cl::Program( std::string( example_string.begin() + 1, example_string.end() - 2 ) );

	program.build();


	// OpenCL側に結果を書き込む領域を作成する
	const size_t
		length = 0x10;
	cl::Buffer
		array( CL_MEM_READ_ONLY, length * sizeof( float ) );


	// OpenCL側のExample関数を作成する 
	cl::make_kernel<cl::Buffer>
		example( program, "Example" );

	// OpenCL側の広域並列数
	cl::EnqueueArgs
		enqueue_args = cl::NDRange( length );

	// Example関数を実行( 呼び出し指示を命令Queueへ追加 )
	for( signed i = 0; i < 0x10; ++i )
	{
		example( enqueue_args, array );
	}

	std::cerr << "Quit Order" << std::endl;

	// OpenCLの処理結果を受け取る領域を作り結果を書き込む
	std::vector<float>
		buffer;

	buffer.resize( length );
#if 0
	// こちらを使うとbufferの書き換えが一切おこらず上手く行かない
	cl::copy( array, buffer.begin(), buffer.end() );
#else
	// こちらを使うと想定通りbufferが-1で埋め尽くされる
	cl::enqueueReadBuffer
	(
	 array,
	 CL_TRUE,
	 0,
	 length * sizeof( float ),
	 &buffer[0]
	);
#endif

	// 処理結果の確認
	for( size_t i = 0; i < length; ++i )
	{
		std::cerr << "Result: " << buffer[i] << std::endl;
	}

	std::cerr << "End" << std::endl;
	
	return EXIT_SUCCESS;
}
catch( const cl::Error &error )
{
	std::cerr 
		<< "ERROR: "
		<< error.what()
		<< "("
		<< LookupErrorMessageWhere( error.err() )
		<< ")"
		<< std::endl;

	return EXIT_FAILURE;
}
```

色付け追加

0
本文
 ```
 
 どなたかご教示お願いいたします。
-```
+```cpp
 // Errorは全て例外処理で受け取る
 #define __CL_ENABLE_EXCEPTIONS
 

OpenCLのcl::copyが上手く動かない

 OpenCLの動作確認用に下記のCodeを作成しました。
下記のCodeのうち#if 0を書き換えて、enqueueReadBuffer()を使わず、
cl::copy()を使うようにすると正しくOpenCL側の処理結果を取得できません。
何故でしょうか?( 結果がおかしいだけで例外やErrorは発生していません )

 cl::copyの中では、clEnqueueMapBufferとclEnqueueUnmapMemObjectが
使われているのですが、これらの関数を正しく呼び出せる条件をわたしが
間違えているようにも思います。

 今回使用した環境ですが、下記になります。

OS:                 Fedora 17
OpenCL Platform:    AMD Accelerated Parallel Processing
CPU:                AMD A8-3850 APU with Radeon(tm) HD Graphics
主記憶容量:            15.1GB

どなたかご教示お願いいたします。

// Errorは全て例外処理で受け取る
#define __CL_ENABLE_EXCEPTIONS

#if defined( __APPLE__) || defined(__MACOSX )
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include <cstdio>
#include <cstdlib>
#include <iostream>

/**
 * Error codeから処理失敗時の通知を作成する
 */
inline const char *LookupErrorMessageWhere( cl_int code )
{
    //省略
}

#define QUOTE(string) #string
const std::string
    example_string =
    QUOTE
    ((
        /**
         * 単に入力した配列に-1を書き込むだけのOpenCL関数
         */
        __kernel void Example( __global float out[] )
        { 
            /* 大域の1次元目の識別子に従って配列を-1で埋める */
            out[get_global_id( 0 )] = -1;
        }
    ));

/**
 * OpenCLの動作を確認するためだけのProgram
 * 本来であれば、標準出力に下記の様な文字列を吐き出す
 *
 * -------------------------------------------------------
 * Quit Order
 * Result: -1 
 * Result: -1 
 * Result: -1 
 * Result: -1 
 *     ・
 *     ・
 *     ・
 * End
 * -------------------------------------------------------
 * OpenCLがGPUで処理するかCPUで処理しているかは、
 * 今回OpenCLの各ClassのgetDefault()にまかせているため不定。
 */
signed main( signed, const char*[] )
try
{
    // OpenCL側にShader実行形式を作成する
    cl::Program
        program = cl::Program( std::string( example_string.begin() + 1, example_string.end() - 2 ) );

    program.build();


    // OpenCL側に結果を書き込む領域を作成する
    const size_t
        length = 0x10;
    cl::Buffer
        array( CL_MEM_READ_ONLY, length * sizeof( float ) );


    // OpenCL側のExample関数を作成する 
    cl::make_kernel<cl::Buffer>
        example( program, "Example" );

    // OpenCL側の大域での反復数
    cl::EnqueueArgs
        enqueue_args = cl::NDRange( length );

    // Example関数を実行( 呼び出し指示を命令Queueへ追加 )
    for( signed i = 0; i < 0x10; ++i )
    {
        example( enqueue_args, array );
    }

    std::cerr << "Quit Order" << std::endl;

    // OpenCLの処理結果を受け取る領域を作り結果を書き込む
    std::vector<float>
        buffer;

    buffer.resize( length );
#if 0
    // こちらを使うとbufferの書き換えが一切おこらず上手く行かない
    cl::copy( array, buffer.begin(), buffer.end() );
#else
    // こちらを使うと想定通りbufferが-1で埋め尽くされる
    cl::enqueueReadBuffer
    (
     array,
     CL_TRUE,
     0,
     length * sizeof( float ),
     &buffer[0]
    );
#endif

    // 処理結果の確認
    for( size_t i = 0; i < length; ++i )
    {
        std::cerr << "Result: " << buffer[i] << std::endl;
    }

    std::cerr << "End" << std::endl;

    return EXIT_SUCCESS;
}
catch( const cl::Error &error )
{
    std::cerr 
        << "ERROR: "
        << error.what()
        << "("
        << LookupErrorMessageWhere( error.err() )
        << ")"
        << std::endl;

    return EXIT_FAILURE;
}
 OpenCLの動作確認用に下記のCodeを作成しました。
下記のCodeのうち#if 0を書き換えて、enqueueReadBuffer()を使わず、
cl::copy()を使うようにすると正しくOpenCL側の処理結果を取得できません。
何故でしょうか?( 結果がおかしいだけで例外やErrorは発生していません )

 cl::copyの中では、clEnqueueMapBufferとclEnqueueUnmapMemObjectが
使われているのですが、これらの関数を正しく呼び出せる条件をわたしが
間違えているようにも思います。

 今回使用した環境ですが、下記になります。
```
OS:					Fedora 17
OpenCL Platform:	AMD Accelerated Parallel Processing
CPU:				AMD A8-3850 APU with Radeon(tm) HD Graphics
主記憶容量:			15.1GB
```

どなたかご教示お願いいたします。
```cpp
// Errorは全て例外処理で受け取る
#define __CL_ENABLE_EXCEPTIONS

#if defined( __APPLE__) || defined(__MACOSX )
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include <cstdio>
#include <cstdlib>
#include <iostream>

/**
 * Error codeから処理失敗時の通知を作成する
 */
inline const char *LookupErrorMessageWhere( cl_int code )
{
	//省略
}

#define QUOTE(string) #string
const std::string
	example_string =
	QUOTE
	((
	  	/**
		 * 単に入力した配列に-1を書き込むだけのOpenCL関数
		 */
		__kernel void Example( __global float out[] )
		{ 
			/* 大域の1次元目の識別子に従って配列を-1で埋める */
			out[get_global_id( 0 )] = -1;
		}
	));

/**
 * OpenCLの動作を確認するためだけのProgram
 * 本来であれば、標準出力に下記の様な文字列を吐き出す
 *
 * -------------------------------------------------------
 * Quit Order
 * Result: -1 
 * Result: -1 
 * Result: -1 
 * Result: -1 
 *     ・
 *     ・
 *     ・
 * End
 * -------------------------------------------------------
 * OpenCLがGPUで処理するかCPUで処理しているかは、
 * 今回OpenCLの各ClassのgetDefault()にまかせているため不定。
 */
signed main( signed, const char*[] )
try
{
	// OpenCL側にShader実行形式を作成する
	cl::Program
		program = cl::Program( std::string( example_string.begin() + 1, example_string.end() - 2 ) );

	program.build();


	// OpenCL側に結果を書き込む領域を作成する
	const size_t
		length = 0x10;
	cl::Buffer
		array( CL_MEM_READ_ONLY, length * sizeof( float ) );


	// OpenCL側のExample関数を作成する 
	cl::make_kernel<cl::Buffer>
		example( program, "Example" );

	// OpenCL側の大域での反復数
	cl::EnqueueArgs
		enqueue_args = cl::NDRange( length );

	// Example関数を実行( 呼び出し指示を命令Queueへ追加 )
	for( signed i = 0; i < 0x10; ++i )
	{
		example( enqueue_args, array );
	}

	std::cerr << "Quit Order" << std::endl;

	// OpenCLの処理結果を受け取る領域を作り結果を書き込む
	std::vector<float>
		buffer;

	buffer.resize( length );
#if 0
	// こちらを使うとbufferの書き換えが一切おこらず上手く行かない
	cl::copy( array, buffer.begin(), buffer.end() );
#else
	// こちらを使うと想定通りbufferが-1で埋め尽くされる
	cl::enqueueReadBuffer
	(
	 array,
	 CL_TRUE,
	 0,
	 length * sizeof( float ),
	 &buffer[0]
	);
#endif

	// 処理結果の確認
	for( size_t i = 0; i < length; ++i )
	{
		std::cerr << "Result: " << buffer[i] << std::endl;
	}

	std::cerr << "End" << std::endl;
	
	return EXIT_SUCCESS;
}
catch( const cl::Error &error )
{
	std::cerr 
		<< "ERROR: "
		<< error.what()
		<< "("
		<< LookupErrorMessageWhere( error.err() )
		<< ")"
		<< std::endl;

	return EXIT_FAILURE;
}
```

環境情報を追加

0
本文
 間違えているようにも思います。
 
  今回使用した環境ですが、下記になります。
-CPU:       AMD A8-3850 APU with Radeon(tm) HD Graphics
-主記憶容量: 15.1GB
+```
+OS:					Fedora 17
+OpenCL Platform:	AMD Accelerated Parallel Processing
+CPU:				AMD A8-3850 APU with Radeon(tm) HD Graphics
+主記憶容量:			15.1GB
+```
 
 どなたかご教示お願いいたします。
 ```

OpenCLのcl::copyが上手く動かない

 OpenCLの動作確認用に下記のCodeを作成しました。
下記のCodeのうち#if 0を書き換えて、enqueueReadBuffer()を使わず、
cl::copy()を使うようにすると正しくOpenCL側の処理結果を取得できません。
何故でしょうか?( 結果がおかしいだけで例外やErrorは発生していません )

 cl::copyの中では、clEnqueueMapBufferとclEnqueueUnmapMemObjectが
使われているのですが、これらの関数を正しく呼び出せる条件をわたしが
間違えているようにも思います。

 今回使用した環境ですが、下記になります。

OS:                 Fedora 17
OpenCL Platform:    AMD Accelerated Parallel Processing
CPU:                AMD A8-3850 APU with Radeon(tm) HD Graphics
主記憶容量:            15.1GB

どなたかご教示お願いいたします。

// Errorは全て例外処理で受け取る
#define __CL_ENABLE_EXCEPTIONS

#if defined( __APPLE__) || defined(__MACOSX )
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include <cstdio>
#include <cstdlib>
#include <iostream>

/**
 * Error codeから処理失敗時の通知を作成する
 */
inline const char *LookupErrorMessageWhere( cl_int code )
{
    //省略
}

#define QUOTE(string) #string
const std::string
    example_string =
    QUOTE
    ((
        /**
         * 単に入力した配列に-1を書き込むだけのOpenCL関数
         */
        __kernel void Example( __global float out[] )
        { 
            /* 大域の1次元目の識別子に従って配列を-1で埋める */
            out[get_global_id( 0 )] = -1;
        }
    ));

/**
 * OpenCLの動作を確認するためだけのProgram
 * 本来であれば、標準出力に下記の様な文字列を吐き出す
 *
 * -------------------------------------------------------
 * Quit Order
 * Result: -1 
 * Result: -1 
 * Result: -1 
 * Result: -1 
 *     ・
 *     ・
 *     ・
 * End
 * -------------------------------------------------------
 * OpenCLがGPUで処理するかCPUで処理しているかは、
 * 今回OpenCLの各ClassのgetDefault()にまかせているため不定。
 */
signed main( signed, const char*[] )
try
{
    // OpenCL側にShader実行形式を作成する
    cl::Program
        program = cl::Program( std::string( example_string.begin() + 1, example_string.end() - 2 ) );

    program.build();


    // OpenCL側に結果を書き込む領域を作成する
    const size_t
        length = 0x10;
    cl::Buffer
        array( CL_MEM_READ_ONLY, length * sizeof( float ) );


    // OpenCL側のExample関数を作成する 
    cl::make_kernel<cl::Buffer>
        example( program, "Example" );

    // OpenCL側の大域での反復数
    cl::EnqueueArgs
        enqueue_args = cl::NDRange( length );

    // Example関数を実行( 呼び出し指示を命令Queueへ追加 )
    for( signed i = 0; i < 0x10; ++i )
    {
        example( enqueue_args, array );
    }

    std::cerr << "Quit Order" << std::endl;

    // OpenCLの処理結果を受け取る領域を作り結果を書き込む
    std::vector<float>
        buffer;

    buffer.resize( length );
#if 0
    // こちらを使うとbufferの書き換えが一切おこらず上手く行かない
    cl::copy( array, buffer.begin(), buffer.end() );
#else
    // こちらを使うと想定通りbufferが-1で埋め尽くされる
    cl::enqueueReadBuffer
    (
     array,
     CL_TRUE,
     0,
     length * sizeof( float ),
     &buffer[0]
    );
#endif

    // 処理結果の確認
    for( size_t i = 0; i < length; ++i )
    {
        std::cerr << "Result: " << buffer[i] << std::endl;
    }

    std::cerr << "End" << std::endl;

    return EXIT_SUCCESS;
}
catch( const cl::Error &error )
{
    std::cerr 
        << "ERROR: "
        << error.what()
        << "("
        << LookupErrorMessageWhere( error.err() )
        << ")"
        << std::endl;

    return EXIT_FAILURE;
}
 OpenCLの動作確認用に下記のCodeを作成しました。
下記のCodeのうち#if 0を書き換えて、enqueueReadBuffer()を使わず、
cl::copy()を使うようにすると正しくOpenCL側の処理結果を取得できません。
何故でしょうか?( 結果がおかしいだけで例外やErrorは発生していません )

 cl::copyの中では、clEnqueueMapBufferとclEnqueueUnmapMemObjectが
使われているのですが、これらの関数を正しく呼び出せる条件をわたしが
間違えているようにも思います。

 今回使用した環境ですが、下記になります。
```
OS:					Fedora 17
OpenCL Platform:	AMD Accelerated Parallel Processing
CPU:				AMD A8-3850 APU with Radeon(tm) HD Graphics
主記憶容量:			15.1GB
```

どなたかご教示お願いいたします。
```
// Errorは全て例外処理で受け取る
#define __CL_ENABLE_EXCEPTIONS

#if defined( __APPLE__) || defined(__MACOSX )
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include <cstdio>
#include <cstdlib>
#include <iostream>

/**
 * Error codeから処理失敗時の通知を作成する
 */
inline const char *LookupErrorMessageWhere( cl_int code )
{
	//省略
}

#define QUOTE(string) #string
const std::string
	example_string =
	QUOTE
	((
	  	/**
		 * 単に入力した配列に-1を書き込むだけのOpenCL関数
		 */
		__kernel void Example( __global float out[] )
		{ 
			/* 大域の1次元目の識別子に従って配列を-1で埋める */
			out[get_global_id( 0 )] = -1;
		}
	));

/**
 * OpenCLの動作を確認するためだけのProgram
 * 本来であれば、標準出力に下記の様な文字列を吐き出す
 *
 * -------------------------------------------------------
 * Quit Order
 * Result: -1 
 * Result: -1 
 * Result: -1 
 * Result: -1 
 *     ・
 *     ・
 *     ・
 * End
 * -------------------------------------------------------
 * OpenCLがGPUで処理するかCPUで処理しているかは、
 * 今回OpenCLの各ClassのgetDefault()にまかせているため不定。
 */
signed main( signed, const char*[] )
try
{
	// OpenCL側にShader実行形式を作成する
	cl::Program
		program = cl::Program( std::string( example_string.begin() + 1, example_string.end() - 2 ) );

	program.build();


	// OpenCL側に結果を書き込む領域を作成する
	const size_t
		length = 0x10;
	cl::Buffer
		array( CL_MEM_READ_ONLY, length * sizeof( float ) );


	// OpenCL側のExample関数を作成する 
	cl::make_kernel<cl::Buffer>
		example( program, "Example" );

	// OpenCL側の大域での反復数
	cl::EnqueueArgs
		enqueue_args = cl::NDRange( length );

	// Example関数を実行( 呼び出し指示を命令Queueへ追加 )
	for( signed i = 0; i < 0x10; ++i )
	{
		example( enqueue_args, array );
	}

	std::cerr << "Quit Order" << std::endl;

	// OpenCLの処理結果を受け取る領域を作り結果を書き込む
	std::vector<float>
		buffer;

	buffer.resize( length );
#if 0
	// こちらを使うとbufferの書き換えが一切おこらず上手く行かない
	cl::copy( array, buffer.begin(), buffer.end() );
#else
	// こちらを使うと想定通りbufferが-1で埋め尽くされる
	cl::enqueueReadBuffer
	(
	 array,
	 CL_TRUE,
	 0,
	 length * sizeof( float ),
	 &buffer[0]
	);
#endif

	// 処理結果の確認
	for( size_t i = 0; i < length; ++i )
	{
		std::cerr << "Result: " << buffer[i] << std::endl;
	}

	std::cerr << "End" << std::endl;
	
	return EXIT_SUCCESS;
}
catch( const cl::Error &error )
{
	std::cerr 
		<< "ERROR: "
		<< error.what()
		<< "("
		<< LookupErrorMessageWhere( error.err() )
		<< ")"
		<< std::endl;

	return EXIT_FAILURE;
}
```

質問を投稿

OpenCLのcl::copyが上手く動かない

 OpenCLの動作確認用に下記のCodeを作成しました。
下記のCodeのうち#if 0を書き換えて、enqueueReadBuffer()を使わず、
cl::copy()を使うようにすると正しくOpenCL側の処理結果を取得できません。
何故でしょうか?( 結果がおかしいだけで例外やErrorは発生していません )

 cl::copyの中では、clEnqueueMapBufferとclEnqueueUnmapMemObjectが
使われているのですが、これらの関数を正しく呼び出せる条件をわたしが
間違えているようにも思います。

 今回使用した環境ですが、下記になります。
CPU: AMD A8-3850 APU with Radeon(tm) HD Graphics
主記憶容量: 15.1GB

どなたかご教示お願いいたします。

// Errorは全て例外処理で受け取る
#define __CL_ENABLE_EXCEPTIONS

#if defined( __APPLE__) || defined(__MACOSX )
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include <cstdio>
#include <cstdlib>
#include <iostream>

/**
 * Error codeから処理失敗時の通知を作成する
 */
inline const char *LookupErrorMessageWhere( cl_int code )
{
    //省略
}

#define QUOTE(string) #string
const std::string
    example_string =
    QUOTE
    ((
        /**
         * 単に入力した配列に-1を書き込むだけのOpenCL関数
         */
        __kernel void Example( __global float out[] )
        { 
            /* 大域の1次元目の識別子に従って配列を-1で埋める */
            out[get_global_id( 0 )] = -1;
        }
    ));

/**
 * OpenCLの動作を確認するためだけのProgram
 * 本来であれば、標準出力に下記の様な文字列を吐き出す
 *
 * -------------------------------------------------------
 * Quit Order
 * Result: -1 
 * Result: -1 
 * Result: -1 
 * Result: -1 
 *     ・
 *     ・
 *     ・
 * End
 * -------------------------------------------------------
 * OpenCLがGPUで処理するかCPUで処理しているかは、
 * 今回OpenCLの各ClassのgetDefault()にまかせているため不定。
 */
signed main( signed, const char*[] )
try
{
    // OpenCL側にShader実行形式を作成する
    cl::Program
        program = cl::Program( std::string( example_string.begin() + 1, example_string.end() - 2 ) );

    program.build();


    // OpenCL側に結果を書き込む領域を作成する
    const size_t
        length = 0x10;
    cl::Buffer
        array( CL_MEM_READ_ONLY, length * sizeof( float ) );


    // OpenCL側のExample関数を作成する 
    cl::make_kernel<cl::Buffer>
        example( program, "Example" );

    // OpenCL側の大域での反復数
    cl::EnqueueArgs
        enqueue_args = cl::NDRange( length );

    // Example関数を実行( 呼び出し指示を命令Queueへ追加 )
    for( signed i = 0; i < 0x10; ++i )
    {
        example( enqueue_args, array );
    }

    std::cerr << "Quit Order" << std::endl;

    // OpenCLの処理結果を受け取る領域を作り結果を書き込む
    std::vector<float>
        buffer;

    buffer.resize( length );
#if 0
    // こちらを使うとbufferの書き換えが一切おこらず上手く行かない
    cl::copy( array, buffer.begin(), buffer.end() );
#else
    // こちらを使うと想定通りbufferが-1で埋め尽くされる
    cl::enqueueReadBuffer
    (
     array,
     CL_TRUE,
     0,
     length * sizeof( float ),
     &buffer[0]
    );
#endif

    // 処理結果の確認
    for( size_t i = 0; i < length; ++i )
    {
        std::cerr << "Result: " << buffer[i] << std::endl;
    }

    std::cerr << "End" << std::endl;

    return EXIT_SUCCESS;
}
catch( const cl::Error &error )
{
    std::cerr 
        << "ERROR: "
        << error.what()
        << "("
        << LookupErrorMessageWhere( error.err() )
        << ")"
        << std::endl;

    return EXIT_FAILURE;
}
 OpenCLの動作確認用に下記のCodeを作成しました。
下記のCodeのうち#if 0を書き換えて、enqueueReadBuffer()を使わず、
cl::copy()を使うようにすると正しくOpenCL側の処理結果を取得できません。
何故でしょうか?( 結果がおかしいだけで例外やErrorは発生していません )

 cl::copyの中では、clEnqueueMapBufferとclEnqueueUnmapMemObjectが
使われているのですが、これらの関数を正しく呼び出せる条件をわたしが
間違えているようにも思います。

 今回使用した環境ですが、下記になります。
CPU:       AMD A8-3850 APU with Radeon(tm) HD Graphics
主記憶容量: 15.1GB

どなたかご教示お願いいたします。
```
// Errorは全て例外処理で受け取る
#define __CL_ENABLE_EXCEPTIONS

#if defined( __APPLE__) || defined(__MACOSX )
#include <OpenCL/cl.hpp>
#else
#include <CL/cl.hpp>
#endif
#include <cstdio>
#include <cstdlib>
#include <iostream>

/**
 * Error codeから処理失敗時の通知を作成する
 */
inline const char *LookupErrorMessageWhere( cl_int code )
{
	//省略
}

#define QUOTE(string) #string
const std::string
	example_string =
	QUOTE
	((
	  	/**
		 * 単に入力した配列に-1を書き込むだけのOpenCL関数
		 */
		__kernel void Example( __global float out[] )
		{ 
			/* 大域の1次元目の識別子に従って配列を-1で埋める */
			out[get_global_id( 0 )] = -1;
		}
	));

/**
 * OpenCLの動作を確認するためだけのProgram
 * 本来であれば、標準出力に下記の様な文字列を吐き出す
 *
 * -------------------------------------------------------
 * Quit Order
 * Result: -1 
 * Result: -1 
 * Result: -1 
 * Result: -1 
 *     ・
 *     ・
 *     ・
 * End
 * -------------------------------------------------------
 * OpenCLがGPUで処理するかCPUで処理しているかは、
 * 今回OpenCLの各ClassのgetDefault()にまかせているため不定。
 */
signed main( signed, const char*[] )
try
{
	// OpenCL側にShader実行形式を作成する
	cl::Program
		program = cl::Program( std::string( example_string.begin() + 1, example_string.end() - 2 ) );

	program.build();


	// OpenCL側に結果を書き込む領域を作成する
	const size_t
		length = 0x10;
	cl::Buffer
		array( CL_MEM_READ_ONLY, length * sizeof( float ) );


	// OpenCL側のExample関数を作成する 
	cl::make_kernel<cl::Buffer>
		example( program, "Example" );

	// OpenCL側の大域での反復数
	cl::EnqueueArgs
		enqueue_args = cl::NDRange( length );

	// Example関数を実行( 呼び出し指示を命令Queueへ追加 )
	for( signed i = 0; i < 0x10; ++i )
	{
		example( enqueue_args, array );
	}

	std::cerr << "Quit Order" << std::endl;

	// OpenCLの処理結果を受け取る領域を作り結果を書き込む
	std::vector<float>
		buffer;

	buffer.resize( length );
#if 0
	// こちらを使うとbufferの書き換えが一切おこらず上手く行かない
	cl::copy( array, buffer.begin(), buffer.end() );
#else
	// こちらを使うと想定通りbufferが-1で埋め尽くされる
	cl::enqueueReadBuffer
	(
	 array,
	 CL_TRUE,
	 0,
	 length * sizeof( float ),
	 &buffer[0]
	);
#endif

	// 処理結果の確認
	for( size_t i = 0; i < length; ++i )
	{
		std::cerr << "Result: " << buffer[i] << std::endl;
	}

	std::cerr << "End" << std::endl;
	
	return EXIT_SUCCESS;
}
catch( const cl::Error &error )
{
	std::cerr 
		<< "ERROR: "
		<< error.what()
		<< "("
		<< LookupErrorMessageWhere( error.err() )
		<< ")"
		<< std::endl;

	return EXIT_FAILURE;
}
```