Skip to content

Commit c223b2b

Browse files
Add real-to-complex 1D sample. (ROCm#172)
* Add real-to-complex 1D sample.
1 parent 70bb5eb commit c223b2b

File tree

3 files changed

+148
-18
lines changed

3 files changed

+148
-18
lines changed

docs/samples/CMakeLists.txt

+12-7
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,19 @@ PROJECT(rocfft_samples CXX)
66
find_package(hip)
77
find_package(rocfft)
88

9-
add_executable(complex_1d complex_1d.cpp)
10-
target_link_libraries( complex_1d PRIVATE roc::rocfft hip::hip_hcc )
11-
target_include_directories( complex_1d PRIVATE ${rocfft_INCLUDE_DIR} )
12-
set_target_properties( complex_1d PROPERTIES CXX_STANDARD_REQUIRED ON)
13-
set_target_properties( complex_1d PROPERTIES CXX_STANDARD 14)
9+
set (samples complex_1d real2complex_1d)
1410

15-
# prevent issue where __float128 is not supported
16-
set_target_properties( complex_1d PROPERTIES CXX_EXTENSIONS OFF)
11+
foreach( exe ${samples} )
12+
add_executable(${exe} "${exe}.cpp")
13+
14+
target_link_libraries( ${exe} PRIVATE roc::rocfft hip::hip_hcc )
15+
target_include_directories( ${exe} PRIVATE ${rocfft_INCLUDE_DIR} )
16+
set_target_properties( ${exe} PROPERTIES CXX_STANDARD_REQUIRED ON)
17+
set_target_properties( ${exe} PROPERTIES CXX_STANDARD 14)
18+
19+
# prevent issue where __float128 is not supported
20+
set_target_properties( ${exe} PROPERTIES CXX_EXTENSIONS OFF)
21+
endforeach()
1722

1823
# Build release by default
1924
if(NOT CMAKE_BUILD_TYPE)

docs/samples/complex_1d.cpp

+5-11
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
21
#include <algorithm>
32
#include <cmath>
43
#include <cstdio>
@@ -12,7 +11,7 @@
1211

1312
int main()
1413
{
15-
// For size N <= 4096
14+
// The problem size
1615
const size_t N = 8;
1716

1817
std::cout << "Complex 1d in-place FFT example\n";
@@ -32,19 +31,14 @@ int main()
3231
}
3332
std::cout << "\n";
3433

35-
// rocfft gpu compute
36-
// ========================================
37-
3834
rocfft_setup();
3935

40-
size_t Nbytes = N * sizeof(float2);
41-
4236
// Create HIP device object.
4337
float2* x;
44-
hipMalloc(&x, Nbytes);
38+
hipMalloc(&x, cx.size() * sizeof(decltype(cx)::value_type));
4539

4640
// Copy data to device
47-
hipMemcpy(x, cx.data(), Nbytes, hipMemcpyHostToDevice);
41+
hipMemcpy(x, cx.data(), cx.size() * sizeof(decltype(cx)::value_type), hipMemcpyHostToDevice);
4842

4943
// Create plans
5044
rocfft_plan forward = NULL;
@@ -76,7 +70,7 @@ int main()
7670

7771
// Copy result back to host
7872
std::vector<float2> cy(N);
79-
hipMemcpy(cy.data(), x, Nbytes, hipMemcpyDeviceToHost);
73+
hipMemcpy(cy.data(), x, cy.size() * sizeof(decltype(cy)::value_type), hipMemcpyDeviceToHost);
8074

8175
std::cout << "Transformed:\n";
8276
for(size_t i = 0; i < cy.size(); i++)
@@ -91,7 +85,7 @@ int main()
9185
NULL, // out_buffer
9286
NULL); // execution info
9387

94-
hipMemcpy(cy.data(), x, Nbytes, hipMemcpyDeviceToHost);
88+
hipMemcpy(cy.data(), x, cy.size() * sizeof(decltype(cy)::value_type), hipMemcpyDeviceToHost);
9589
std::cout << "Transformed back:\n";
9690
for(size_t i = 0; i < cy.size(); i++)
9791
{

docs/samples/real2complex_1d.cpp

+131
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
#include <algorithm>
2+
#include <cmath>
3+
#include <cstdio>
4+
#include <cstdlib>
5+
#include <iostream>
6+
#include <vector>
7+
8+
#include <hip/hip_runtime_api.h>
9+
10+
#include "rocfft.h"
11+
12+
int main()
13+
{
14+
// The problem size
15+
const size_t N = 8;
16+
17+
std::cout << "Complex 1d in-place FFT example\n";
18+
19+
// Initialize data on the host
20+
std::vector<float> cx(N);
21+
for(size_t i = 0; i < N; i++)
22+
{
23+
cx[i] = i;
24+
}
25+
26+
std::cout << "Input:\n";
27+
for(size_t i = 0; i < N; i++)
28+
{
29+
std::cout << cx[i] << " ";
30+
}
31+
std::cout << "\n";
32+
33+
rocfft_setup();
34+
35+
// Create HIP device objects:
36+
float* x;
37+
hipMalloc(&x, cx.size() * sizeof(decltype(cx)::value_type));
38+
float2* y;
39+
hipMalloc(&y, (N / 2 + 1) * sizeof(float));
40+
41+
// Copy data to device
42+
hipMemcpy(x, cx.data(), cx.size() * sizeof(decltype(cx)::value_type), hipMemcpyHostToDevice);
43+
44+
// Create plans
45+
rocfft_plan forward = NULL;
46+
rocfft_plan_create(&forward,
47+
rocfft_placement_notinplace,
48+
rocfft_transform_type_real_forward,
49+
rocfft_precision_single,
50+
1, // Dimensions
51+
&N, // lengths
52+
1, // Number of transforms
53+
NULL); // Description
54+
55+
// The real-to-complex transform uses work memory, which is passed
56+
// via a rocfft_execution_info struct.
57+
rocfft_execution_info fftinfo;
58+
rocfft_execution_info_create(&fftinfo);
59+
size_t wbuffersize = 0;
60+
rocfft_plan_get_work_buffer_size(forward, &wbuffersize);
61+
void* wbuffer;
62+
hipMalloc(&wbuffer, wbuffersize);
63+
rocfft_execution_info_set_work_buffer(fftinfo, wbuffer, wbuffersize);
64+
65+
// Execute the forward transform
66+
rocfft_execute(forward, // plan
67+
(void**)&x, // in_buffer
68+
(void**)&y, // out_buffer
69+
fftinfo); // execution info
70+
71+
std::cout << "Transformed:\n";
72+
std::vector<float2> cy(N / 2 + 1);
73+
hipMemcpy(cy.data(), y, cy.size() * sizeof(decltype(cy)::value_type), hipMemcpyDeviceToHost);
74+
for(size_t i = 0; i < cy.size(); i++)
75+
{
76+
std::cout << "( " << cy[i].x << "," << cy[i].y << ") ";
77+
}
78+
std::cout << "\n";
79+
80+
// Create plans
81+
rocfft_plan backward = NULL;
82+
rocfft_plan_create(&backward,
83+
rocfft_placement_notinplace,
84+
rocfft_transform_type_real_inverse,
85+
rocfft_precision_single,
86+
1, // Dimensions
87+
&N, // lengths
88+
1, // Number of transforms
89+
NULL); // Description
90+
91+
// Execute the backward transform
92+
rocfft_execute(backward, // plan
93+
(void**)&y, // in_buffer
94+
(void**)&x, // out_buffer
95+
fftinfo); // execution info
96+
97+
std::cout << "Transformed back:\n";
98+
std::vector<float> backx(N);
99+
hipMemcpy(
100+
backx.data(), x, backx.size() * sizeof(decltype(backx)::value_type), hipMemcpyDeviceToHost);
101+
for(size_t i = 0; i < backx.size(); i++)
102+
{
103+
std::cout << backx[i] << " ";
104+
}
105+
std::cout << "\n";
106+
107+
const float overN = 1.0f / N;
108+
float error = 0.0f;
109+
for(size_t i = 0; i < cx.size(); i++)
110+
{
111+
//std::cout << "i: " << i << "\t" << cx[i] << "\t" << backx[i] << "\n";
112+
float diff = std::abs(backx[i] * overN - cx[i]);
113+
if(diff > error)
114+
{
115+
error = diff;
116+
}
117+
}
118+
std::cout << "Maximum error: " << error << "\n";
119+
120+
hipFree(x);
121+
hipFree(y);
122+
hipFree(wbuffer);
123+
124+
// Destroy plans
125+
rocfft_plan_destroy(forward);
126+
rocfft_plan_destroy(backward);
127+
128+
rocfft_cleanup();
129+
130+
return 0;
131+
}

0 commit comments

Comments
 (0)