Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FFTW preset, how to define fftw_iodim for guru interface? #466

Closed
hageldave opened this issue Sep 19, 2017 · 5 comments
Closed

FFTW preset, how to define fftw_iodim for guru interface? #466

hageldave opened this issue Sep 19, 2017 · 5 comments
Labels

Comments

@hageldave
Copy link

hageldave commented Sep 19, 2017

Hey, so I' trying to figure out on how to create the iodims parameter for the guru interface planner method:

public static native fftw_plan fftw_plan_guru_split_dft_r2c(
                             int rank, @Const fftw_iodim dims,
			     int howmany_rank,
			     @Const fftw_iodim howmany_dims, double[] in, double[] ro, double[] io,
			     @Cast("unsigned") int flags);

This is the oficial fftw documentation on this method: http://www.fftw.org/fftw3_doc/Guru-Real_002ddata-DFTs.html#Guru-Real_002ddata-DFTs

So in cpp the dims argument could be generated like so:

std::vector<fftw_iodim> ioDims;
ioDims.push_back({width, 1,1});
ioDims.push_back({height, width, width});
ioDims.push_back({1,width*height, width*height});
fftw_plan p = fftw_plan_guru_split_dft_r2c(
   3, ioDims.data(), 
   0, NULL, 
   realIn, realOut, imagOut
   FFTW_ESTIMATE);

In java however I cannot figure out on how to create the ioDims array due to the crazy pointering.
I've been trying the following (used do_not_use_me because its the only iodim class that lets me set its parameters in an easy way):

fftw_iodim_do_not_use_me d0 = new fftw_iodim_do_not_use_me().n(width).is(1).os(1);
fftw_iodim_do_not_use_me d1 = new fftw_iodim_do_not_use_me().n(height).is(width).os(width);
fftw_iodim_do_not_use_me d2 = new fftw_iodim_do_not_use_me().n(1).is(width*height).os(width*height);
fftw_iodim dims = new fftw_iodim(d0).put(d1).put(d2);

fftw_plan plan = fftw3.fftw_plan_guru_split_dft_r2c(
   3, dims, 
   0, null, 
   inR, outR, outI, 
   (int)fftw3.FFTW_ESTIMATE);

but this gives me fftw: alloc.c:269: assertion failed: p
How am I supposed to do this correctly?

@saudet
Copy link
Member

saudet commented Sep 19, 2017 via email

@hageldave
Copy link
Author

Thanks for the quick answer.
I'm using the following maven release (which i believe is the latest release, as 3.3.6 is still SNAPSHOT)

<groupId>org.bytedeco.javacpp-presets</groupId>
<artifactId>fftw-platform</artifactId>
<version>3.3.5-1.3</version>

There seems to be no such constructor new fftw_iodim(int n) which would let me specify an array length. The only constructors present are:
new fftw_iodim() and new fftw_iodim(Pointer p).
So do I have to use calloc or realloc to allocate a void* array , put my fftw_iodim in there and then use the pointer cast constructor new fftw_iodim(Pointer p) with that array?

Also, suppose I would not use the fftw_iodim_do_not_use_me class but instead the normal fftw_iodim, how would I set the parameters?

@hageldave
Copy link
Author

Alright I figured it out, I guess. It seems like you have to use the fftw_iodim_do_not_use_me class (what exactly does that name imply?) as this class has the array constructor. Also Loader.sizeof(fftw_iodim.class); throws a NullpointerException whereas Loader.sizeof(fftw_iodim_do_not_use_me.class); returns 12 (3*4bytes). So what I ended up doing was
Creating a fftw_iodim_do_not_use_me array, setting its contents using position(long) and put(Pointer) and then using the pointer cast constructor of fftw_iodim(Pointer) with that array.

static void execSplit2D(int width, int height, double[] inR, double[] outR, double[] outI){
	try(
			fftw_iodim_do_not_use_me d0 = new fftw_iodim_do_not_use_me();
			fftw_iodim_do_not_use_me d1 = new fftw_iodim_do_not_use_me();
			fftw_iodim_do_not_use_me d2 = new fftw_iodim_do_not_use_me();
			fftw_iodim_do_not_use_me array = new fftw_iodim_do_not_use_me(3);
			fftw_iodim dims = new fftw_iodim(array);
	){
		d0.n(width).is(1).os(1);
		d1.n(height).is(width).os(width);
		d2.n(1).is(width*height).os(width*height);
		array.position(0).put(d0).position(1).put(d1).position(2).put(d2);
		fftw_plan plan = fftw3.fftw_plan_guru_split_dft_r2c(
				3, dims, 
				0, null, 
				inR, outR, outI, 
				(int)fftw3.FFTW_ESTIMATE);
		fftw3.fftw_execute_split_dft_r2c(plan, inR, outR, outI);
	}
}

@saudet
Copy link
Member

saudet commented Sep 20, 2017

I see, the definition of fftw_iodim is missing. We'll need to locate it and add it.

@saudet
Copy link
Member

saudet commented Sep 23, 2017

Fixed in the commit above! Thanks for reporting.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants