[clfft] 17/128: Precallback - Added few Google Test test cases
Ghislain Vaillant
ghisvail-guest at moszumanska.debian.org
Thu Oct 22 14:54:33 UTC 2015
This is an automated email from the git hooks/post-receive script.
ghisvail-guest pushed a commit to branch master
in repository clfft.
commit 2a3e9bb0745d60391cda50f846a6d64e32a05448
Author: Pradeep <pradeep.rao at amd.com>
Date: Tue Aug 18 11:49:52 2015 +0530
Precallback - Added few Google Test test cases
---
src/tests/CMakeLists.txt | 1 +
src/tests/accuracy_test_common.h | 88 ++++++++++++++++++++
src/tests/accuracy_test_precallback.cpp | 143 ++++++++++++++++++++++++++++++++
src/tests/buffer.h | 23 +++++
src/tests/cl_transform.h | 80 +++++++++++++++++-
src/tests/fftw_transform.h | 17 ++++
src/tests/test_constants.h | 50 +++++++++++
7 files changed, 401 insertions(+), 1 deletion(-)
diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt
index 88904b5..d08ead6 100644
--- a/src/tests/CMakeLists.txt
+++ b/src/tests/CMakeLists.txt
@@ -27,6 +27,7 @@ set( clFFT.Test.Source
accuracy_test_pow5.cpp
accuracy_test_mixed_radices.cpp
accuracy_test_random.cpp
+ accuracy_test_precallback.cpp
gtest_main.cpp
${PROJECT_SOURCE_DIR}/client/openCL.misc.cpp
c-compliance.c
diff --git a/src/tests/accuracy_test_common.h b/src/tests/accuracy_test_common.h
index 428bd8b..159cde4 100644
--- a/src/tests/accuracy_test_common.h
+++ b/src/tests/accuracy_test_common.h
@@ -119,6 +119,94 @@ void complex_to_complex( data_pattern pattern, direction::direction_t direction,
/*****************************************************/
/*****************************************************/
+// complex to complex transform with precallback
+// dimension is inferred from lengths.size()
+// tightly packed is inferred from strides.empty()
+template< class T, class cl_T, class fftw_T >
+void precallback_complex_to_complex( data_pattern pattern, direction::direction_t direction,
+ std::vector<size_t> lengths, size_t batch,
+ std::vector<size_t> input_strides, std::vector<size_t> output_strides,
+ size_t input_distance, size_t output_distance,
+ layout::buffer_layout_t in_layout, layout::buffer_layout_t out_layout,
+ placeness::placeness_t placeness, bool hasUserDatatype = false,
+ T scale = 1.0f )
+{
+ clfft<T, cl_T> test_fft( static_cast<clfftDim>(lengths.size()), &lengths[0],
+ input_strides.empty() ? NULL : &input_strides[0],
+ output_strides.empty() ? NULL : &output_strides[0],
+ batch, input_distance, output_distance,
+ cl_layout(in_layout), cl_layout(out_layout),
+ cl_placeness(placeness) );
+
+ fftw<T, fftw_T> reference( lengths.size(), &lengths[0], batch, c2c );
+
+ //initialize input
+ if( pattern == sawtooth )
+ {
+ test_fft.set_input_to_sawtooth( 1.0f );
+ reference.set_data_to_sawtooth( 1.0f );
+ }
+ else if( pattern == value )
+ {
+ test_fft.set_input_to_value( 2.0f, 2.5f );
+ reference.set_all_data_to_value( 2.0f, 2.5f );
+ }
+ else if( pattern == impulse )
+ {
+ test_fft.set_input_to_impulse();
+ reference.set_data_to_impulse();
+ }
+ else if( pattern == erratic )
+ {
+ test_fft.set_input_to_random();
+ reference.set_data_to_random();
+ }
+ else
+ {
+ throw std::runtime_error( "invalid pattern type in complex_to_complex()" );
+ }
+
+ // if we're starting with unequal data, we're destined for failure
+ EXPECT_EQ( true, test_fft.input_buffer() == reference.input_buffer() );
+
+ //set precallback values
+ if (hasUserDatatype)
+ {
+ test_fft.set_precallback_complex_userdatatype();
+ }
+ else
+ {
+ test_fft.set_precallback_complex();
+ }
+ reference.set_precallback_complex();
+
+ if( direction == direction::forward )
+ {
+ test_fft.set_forward_transform();
+ test_fft.forward_scale( scale );
+
+ reference.set_forward_transform();
+ reference.forward_scale( scale );
+ }
+ else if( direction == direction::backward )
+ {
+ test_fft.set_backward_transform();
+ test_fft.backward_scale( scale );
+
+ reference.set_backward_transform();
+ reference.backward_scale( scale );
+ }
+ else
+ throw std::runtime_error( "invalid direction in complex_to_complex()" );
+
+ reference.transform();
+ test_fft.transform();
+
+ EXPECT_EQ( true, test_fft.result() == reference.result() );
+}
+
+/*****************************************************/
+/*****************************************************/
// dimension is inferred from lengths.size()
// tightly packed is inferred from strides.empty()
// input layout is always real
diff --git a/src/tests/accuracy_test_precallback.cpp b/src/tests/accuracy_test_precallback.cpp
new file mode 100644
index 0000000..a617017
--- /dev/null
+++ b/src/tests/accuracy_test_precallback.cpp
@@ -0,0 +1,143 @@
+/* ************************************************************************
+ * Copyright 2015 Advanced Micro Devices, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ************************************************************************/
+
+#include <gtest/gtest.h>
+#include<math.h>
+
+#include "test_constants.h"
+#include "fftw_transform.h"
+#include "cl_transform.h"
+#include "typedefs.h"
+#include "accuracy_test_common.h"
+#include <stdexcept>
+#include <vector>
+
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+/*@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*/
+class accuracy_test_precallback_single : public ::testing::Test {
+protected:
+ accuracy_test_precallback_single(){}
+ virtual ~accuracy_test_precallback_single(){}
+ virtual void SetUp(){}
+ virtual void TearDown(){
+ }
+};
+
+class accuracy_test_precallback_double : public ::testing::Test {
+protected:
+ accuracy_test_precallback_double(){}
+ virtual ~accuracy_test_precallback_double(){}
+ virtual void SetUp(){}
+ virtual void TearDown(){
+ }
+};
+
+namespace precallback
+{
+// *****************************************************
+// *****************************************************
+template< class T, class cl_T, class fftw_T >
+void precallback_1D_forward_in_place_complex_interleaved_to_complex_interleaved()
+{
+ std::vector<size_t> lengths;
+ lengths.push_back( normal2 );
+ size_t batch = 1;
+ std::vector<size_t> input_strides;
+ std::vector<size_t> output_strides;
+ size_t input_distance = 0;
+ size_t output_distance = 0;
+ layout::buffer_layout_t in_layout = layout::complex_interleaved;
+ layout::buffer_layout_t out_layout = layout::complex_interleaved;
+ placeness::placeness_t placeness = placeness::in_place;
+ direction::direction_t direction = direction::forward;
+
+ data_pattern pattern = impulse;
+ precallback_complex_to_complex<T, cl_T, fftw_T>( pattern, direction, lengths, batch, input_strides, output_strides, input_distance, output_distance, in_layout, out_layout, placeness );
+}
+
+TEST_F(accuracy_test_precallback_single, precallback_1D_forward_in_place_complex_interleaved_to_complex_interleaved)
+{
+ try { precallback_1D_forward_in_place_complex_interleaved_to_complex_interleaved< float, cl_float, fftwf_complex >(); }
+ catch( const std::exception& err ) { handle_exception(err); }
+}
+
+TEST_F(accuracy_test_precallback_double, precallback_1D_forward_in_place_complex_interleaved_to_complex_interleaved)
+{
+ try { precallback_1D_forward_in_place_complex_interleaved_to_complex_interleaved< double, cl_double, fftw_complex >(); }
+ catch( const std::exception& err ) { handle_exception(err); }
+}
+
+// *****************************************************
+// *****************************************************
+template< class T, class cl_T, class fftw_T >
+void precallback_1D_forward_in_place_complex_planar_to_complex_planar()
+{
+ std::vector<size_t> lengths;
+ lengths.push_back( normal2 );
+ size_t batch = 1;
+ std::vector<size_t> input_strides;
+ std::vector<size_t> output_strides;
+ size_t input_distance = 0;
+ size_t output_distance = 0;
+ layout::buffer_layout_t in_layout = layout::complex_planar;
+ layout::buffer_layout_t out_layout = layout::complex_planar;
+ placeness::placeness_t placeness = placeness::in_place;
+ direction::direction_t direction = direction::forward;
+
+ data_pattern pattern = impulse;
+ precallback_complex_to_complex<T, cl_T, fftw_T>( pattern, direction, lengths, batch, input_strides, output_strides, input_distance, output_distance, in_layout, out_layout, placeness );
+}
+
+TEST_F(accuracy_test_precallback_single, precallback_1D_forward_in_place_complex_planar_to_complex_planar)
+{
+ try { precallback_1D_forward_in_place_complex_planar_to_complex_planar< float, cl_float, fftwf_complex >(); }
+ catch( const std::exception& err ) { handle_exception(err); }
+}
+
+TEST_F(accuracy_test_precallback_double, precallback_1D_forward_in_place_complex_planar_to_complex_planar)
+{
+ try { precallback_1D_forward_in_place_complex_planar_to_complex_planar< double, cl_double, fftw_complex >(); }
+ catch( const std::exception& err ) { handle_exception(err); }
+}
+
+// *****************************************************
+// *****************************************************
+template< class T, class cl_T, class fftw_T >
+void precallback_1D_forward_in_place_complex_to_complex_userdatatype()
+{
+ std::vector<size_t> lengths;
+ lengths.push_back( normal2 );
+ size_t batch = 1;
+ std::vector<size_t> input_strides;
+ std::vector<size_t> output_strides;
+ size_t input_distance = 0;
+ size_t output_distance = 0;
+ layout::buffer_layout_t in_layout = layout::complex_interleaved;
+ layout::buffer_layout_t out_layout = layout::complex_interleaved;
+ placeness::placeness_t placeness = placeness::in_place;
+ direction::direction_t direction = direction::forward;
+
+ data_pattern pattern = impulse;
+ precallback_complex_to_complex<T, cl_T, fftw_T>( pattern, direction, lengths, batch, input_strides, output_strides, input_distance, output_distance, in_layout, out_layout, placeness, true );
+}
+
+TEST_F(accuracy_test_precallback_single, precallback_1D_forward_in_place_complex_to_complex_userdatatype)
+{
+ try { precallback_1D_forward_in_place_complex_to_complex_userdatatype< float, cl_float, fftwf_complex >(); }
+ catch( const std::exception& err ) { handle_exception(err); }
+}
+
+}
\ No newline at end of file
diff --git a/src/tests/buffer.h b/src/tests/buffer.h
index 7fef025..50fc5a5 100644
--- a/src/tests/buffer.h
+++ b/src/tests/buffer.h
@@ -598,6 +598,29 @@ public:
return !( *this == other_buffer );
}
+ void operator*=( buffer<T> & other_buffer )
+ {
+ if( is_interleaved() )
+ {
+ T* base_ptr = _the_buffers[interleaved].ptr();
+
+ for( size_t batch = 0; batch < batch_size(); batch++ )
+ for( size_t z = 0; z < length(dimz); z++ )
+ for( size_t y = 0; y < length(dimy); y++ )
+ for( size_t x = 0; x < length(dimx); x++ )
+ {
+ size_t real_index = index(x, y, z, batch);
+ size_t imag_index = real_index + 1; // the imaginary component immediately follows the real
+
+ *( base_ptr + real_index ) *= other_buffer.real(x, y, z, batch);
+ if (!(this->is_real() || other_buffer.is_real()))
+ {
+ *( base_ptr + imag_index ) *= other_buffer.imag(x, y, z, batch);
+ }
+ }
+ }
+ }
+
/*****************************************************/
// strides and distance are those of the output (that is, the new hermitian buffer)
void change_real_to_hermitian( const size_t* strides_in, const size_t distance_in )
diff --git a/src/tests/cl_transform.h b/src/tests/cl_transform.h
index 776a318..2edf28d 100644
--- a/src/tests/cl_transform.h
+++ b/src/tests/cl_transform.h
@@ -131,7 +131,7 @@ private:
buffer<T> input;
buffer<T> output;
-
+
size_t number_of_data_points;
T _forward_scale, _backward_scale;
cl_uint commandQueueFlags;
@@ -618,6 +618,84 @@ public:
}
/*****************************************************/
+ void set_precallback_complex() {
+ cl_int status = 0;
+ clfftPrecision precision;
+ clfftGetPlanPrecision( *plan_handle, &precision );
+
+ char* precallbackstr;
+
+ if (input.is_interleaved() )
+ {
+ precallbackstr = (precision == CLFFT_SINGLE) ? STRINGIFY(MULVAL) : STRINGIFY(MULVAL_DP);
+ }
+ else if (input.is_planar())
+ {
+ precallbackstr = (precision == CLFFT_SINGLE) ? STRINGIFY(MULVAL_PLANAR) : STRINGIFY(MULVAL_PLANAR_DP);
+ }
+
+ //precallback user data
+ buffer<T> userdata( static_cast<size_t>(dimension),
+ input.lengths(),
+ input.strides(),
+ input.batch_size(),
+ input.distance(),
+ layout::real,
+ _placeness
+ );
+
+ userdata.set_all_to_random_data(lengths[0], 10);
+
+ // make the new buffer
+ const size_t bufferSizeBytes = userdata.size_in_bytes( );
+
+ cl_mem userdataBuff = clCreateBuffer( context.get( ), CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, bufferSizeBytes, userdata.real_ptr(), &status);
+ OPENCL_V_THROW( status, "Creating Buffer ( ::clCreateBuffer() )" );
+
+ //Register the callback
+ OPENCL_V_THROW (clFFTSetPlanCallback(*plan_handle, "mulval", precallbackstr, NULL, 0, PRECALLBACK, userdataBuff), "clFFTSetPlanCallback failed");
+ }
+
+ /*****************************************************/
+ void set_precallback_complex_userdatatype() {
+ cl_int status = 0;
+
+ char* precallbackstr = STRINGIFY(MULVAL_UDT);
+
+ size_t totalPts = input.total_number_of_points_including_data_and_intervening();
+
+ buffer<T> temp( static_cast<size_t>(dimension),
+ input.lengths(),
+ input.strides(),
+ input.batch_size(),
+ input.distance(),
+ layout::real,
+ _placeness
+ );
+
+ temp.set_all_to_random_data(lengths[0], 10);
+
+ std::vector<USER_DATA> userdata(totalPts);
+ size_t the_index;
+ for( size_t batch = 0; batch < input.batch_size(); batch++)
+ for( size_t z = 0; z < input.length(dimz); z++)
+ for( size_t y = 0; y < input.length(dimy); y++)
+ for( size_t x = 0; x < input.length(dimx); x++)
+ {
+ the_index = ( input.stride(dimx) * x + input.stride(dimy) * y + input.stride(dimz) * z + input.distance() * batch );
+
+ userdata[the_index].scalar1 = temp.real(x, y, z, batch);
+ userdata[the_index].scalar2 = 1;
+ }
+
+ cl_mem userdataBuff = clCreateBuffer(context.get( ), CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(USER_DATA) * totalPts, (void*)&userdata[0], &status);
+ OPENCL_V_THROW( status, "Creating Buffer ( ::clCreateBuffer() )" );
+
+ //Register the callback
+ OPENCL_V_THROW (clFFTSetPlanCallback(*plan_handle, "mulval", precallbackstr, STRINGIFY(STRUCT_USERDATA), 0, PRECALLBACK, userdataBuff), "clFFTSetPlanCallback failed");
+ }
+
+ /*****************************************************/
bool device_list_has_devices() {
return !device_id.empty();
}
diff --git a/src/tests/fftw_transform.h b/src/tests/fftw_transform.h
index 8768648..9936b21 100644
--- a/src/tests/fftw_transform.h
+++ b/src/tests/fftw_transform.h
@@ -440,6 +440,23 @@ public:
input = other_buffer;
}
+ void set_precallback_complex()
+ {
+ //precallback user data
+ buffer<T> userdata( input.number_of_dimensions(),
+ input.lengths(),
+ input.strides(),
+ input.batch_size(),
+ input.distance(),
+ layout::real ,
+ cl_placeness(placeness::in_place)
+ );
+
+ userdata.set_all_to_random_data(_lengths[0], 10);
+
+ input *= userdata;
+ }
+
/*****************************************************/
void clear_data_buffer()
{
diff --git a/src/tests/test_constants.h b/src/tests/test_constants.h
index b281da4..cc39769 100644
--- a/src/tests/test_constants.h
+++ b/src/tests/test_constants.h
@@ -23,6 +23,56 @@
#include <string>
#include <stdexcept>
+#define MULVAL float2 mulval(__global void* in, uint offset, __global void* userdata)\n \
+ { \n \
+ float scalar = *((__global float*)userdata + offset); \n \
+ float2 ret = *((__global float2*)in + offset) * scalar; \n \
+ return ret; \n \
+ }
+
+#define MULVAL_UDT float2 mulval(__global void* in, uint offset, __global void* userdata)\n \
+ { \n \
+ __global USER_DATA *data = ((__global USER_DATA *)userdata + offset); \n \
+ float scalar = data->scalar1 * data->scalar2; \n \
+ float2 ret = *((__global float2*)in + offset) * scalar; \n \
+ return ret; \n \
+ }
+
+#define MULVAL_DP double2 mulval(__global void* in, uint offset, __global void* userdata)\n \
+ { \n \
+ double scalar = *((__global double*)userdata + offset); \n \
+ double2 ret = *((__global double2*)in + offset) * scalar; \n \
+ return ret; \n \
+ }
+
+#define MULVAL_PLANAR float2 mulval(__global void* inRe, __global void* inIm, uint offset, __global void* userdata)\n \
+ { \n \
+ float scalar = *((__global float*)userdata + offset); \n \
+ float2 ret; \n \
+ ret.x = *((__global float*)inRe + offset) * scalar; \n \
+ ret.y = *((__global float*)inIm + offset) * scalar; \n \
+ return ret; \n \
+ }
+
+#define MULVAL_PLANAR_DP double2 mulval(__global void* inRe, __global void* inIm, uint offset, __global void* userdata)\n \
+ { \n \
+ double scalar = *((__global double*)userdata + offset); \n \
+ double2 ret; \n \
+ ret.x = *((__global double*)inRe + offset) * scalar; \n \
+ ret.y = *((__global double*)inIm + offset) * scalar; \n \
+ return ret; \n \
+ }
+
+#define STRUCT_USERDATA typedef struct USER_DATA \
+ { \
+ float scalar1; \
+ float scalar2; \
+ } USER_DATA;
+STRUCT_USERDATA
+
+#define CALLBCKSTR(...) #__VA_ARGS__
+#define STRINGIFY(...) CALLBCKSTR(__VA_ARGS__)
+
enum { REAL=0, IMAG=1 };
enum { dimx=0, dimy=1, dimz=2 };
enum fftw_dim { one_d=1, two_d=2, three_d=3 };
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/clfft.git
More information about the debian-science-commits
mailing list