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

Reduced precision complex type #24

Open
samhatfield opened this issue Sep 2, 2016 · 6 comments
Open

Reduced precision complex type #24

samhatfield opened this issue Sep 2, 2016 · 6 comments

Comments

@samhatfield
Copy link
Member

samhatfield commented Sep 2, 2016

I've started to think about how to implement a complex reduced precision type. I'm trying out a few ideas in my own fork, if you fancy taking a look (see L76 and L183). The basic idea is to use a real complex type as a container. Then, after assignment, split up the reduced precision complex variable into its real and imaginary parts, apply truncation to both and then stitch them back together into a real complex type (based on Tobias Thornes' approach).

Here is a usage example:

program main
    use rp_emulator

    implicit none

    complex(kind(1.0d0)) :: x = (1.123412341341234d0, 1.0423412341234d0)
    type(rpe_complex_var) :: y

    y%sbits = 6

    y = x

    print *, x
    print *, y%val
end program

Output:

 (  1.1234123413412340     ,  1.0423412341234000     )
 (  1.1250000000000000     ,  1.0468750000000000     )

What do you think?

@samhatfield
Copy link
Member Author

Looking at the code generator, I'm not sure how best to go about this. I suppose we want the JSON templates to look something like the following:

{"operators":
    [
        {"add":
            {
                "operator": "+",
                "return_types": ["rpe_var", "rpe_complex_var"],
                "operator_categories": ["unary", "binary"]
            }
        },
...
        {"ge":
            {
                "operator": ".GE.",
                "return_types": ["logical"],
                "operator_categories": ["binary"]
            }
        },
...
    ]
}

@samhatfield
Copy link
Member Author

Any thoughts on this @ajdawson ?

@ajdawson
Copy link
Member

I haven't had a chance to look yet, been too busy. Will do at some point soon I expect.

I have an abstract idea of how this should work, but I don't know how it would end up looking.

@samhatfield
Copy link
Member Author

Sure, no problem, it's not urgent.

@ajdawson
Copy link
Member

Come and talk to me about this in person. It is quite complicated and there are several options for how to do it nicely.

@samhatfield
Copy link
Member Author

samhatfield commented Sep 27, 2016

As far as I can tell, the only complex operations I need for SPEEDY are:

  • addition
  • subtraction
  • multiplication
  • conjugation
  • casting to real (that is, taking the real part).

However, occasionally complex arrays are implicitly cast to real arrays, during a function call. The complex elements are unpacked into a real array twice as long. I don't know how this will work with a reduced precision complex type, as I'm unable to make a minimal working example of this casting behaviour, for some reason (it just won't compile).

EDIT: Scratch that, I have a working example. The FFT routines take advantage of the sequential storage of real and imaginary parts of complex numbers in memory. In other words, 4 sequentially stored floats could be interpreted as 4 REALs or 2 COMPLEXs. Unfortunately, such a conversion doesn't work with rpe_var and rpe_complex_var types. I will have to write a function for 'unpacking' complex arrays into real arrays twice as long.

samhatfield pushed a commit to samhatfield/rpe that referenced this issue Nov 2, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants