Re: Undefined values returned by NclReturnValue

From: Mary Haley <haley_at_nyahnyahspammersnyahnyah>
Date: Wed Oct 30 2013 - 14:49:27 MDT

Dear Li,

Thanks for providing the codes offline. I had forgotten you were working with C code and not Fortran code.

I believe the issue is in the way you are allocating the memory for the return variable "imf". I see you are doing the allocation in pieces, which allows you to treat "imf" as a 2D array later:

    /* allocate memory for results */
    /* NOTE: The first column is the original signal */
    *nm = (int)(log2(ns))-1+2;
    *imf = malloc(sizeof(float*)*(*nm));
    for (m = 0; m < *nm; ++m) {
        (*imf)[m] = malloc(sizeof(float)*ns);
    }

When you allocate imf this way, the memory is no longer contiguous. When you return it back to NCL, I think it's expecting the memory to be contiguous.

To fix this, you need to allocate imf as if it were a 1D array:

    float *imf;
    .
    .
    .
    imf = (float*)malloc(sizeof(float)*(*nm)*ns)

This means, then, you will need to figure out the subscripting yourself. You will have to update the code below:

    /* initialize variables and random number generator */
    for (m = 0; m < *nm; ++m) {
        for (i = 0; i < ns; ++i) {
            (*imf)[m][i] = 0.0;
        }

to something like:

    /* initialize variables and random number generator */
    for (m = 0; m < *nm; ++m) {
        for (i = 0; i < ns; ++i) {
           imf[m*ns+i] = 0.0;
        }

You will need to change all refereneces to "imf", because I think you have it set as a double pointer, and in this case, it's only a single pointer.

By the way, if you use calloc instead of malloc, it should automatically initialize the array to 0.0 for you. I'm just using the above "for" loop to show you how the new indexing might look.

--Mary

On Oct 30, 2013, at 9:09 AM, Li Dong <dongli@lasg.iap.ac.cn> wrote:

> Dear Mary,
>
> Thank you for helping! I am writing C code, and the codes are attached. I have copied the 2D array into a 1D array, and the result is right, but it will be convenient that the 2D one works.
>
> Best regards,
>
> Li
> <eemd.tar.gz>
> On Oct 30, 2013, at 10:48 PM, Mary Haley <haley@ucar.edu> wrote:
>
>> Hi Li,
>>
>> Without looking at any code, my guess is that you are calling the function with the wrong type and/or the wrong dimension sizes.
>>
>> First, make sure that if the Fortran routine is using REALs for the arrays, that you use floats inside the NCL script when calling this routine. If the Fortran routine is using DOUBLE PRECISION, then make sure you are using doubles in the NCL script.
>>
>> Also, make sure your dimensions are in the correct order, although I don't think this is the issue here. Remember that if an array is NM x NS in the Fortran code, it will be NS x NM in the C wrapper.
>>
>> Finally, make sure that the array you are returning is the exact same size as what the Fortran routine is expecting.
>>
>> If you continue to have problems, please include the full script, Fortran code, and any needed data files. This is too hard to debug without seeing your code.
>>
>> See:
>>
>> http://www.ncl.ucar.edu/report_bug.shtml
>>
>> Thanks,
>>
>> --Mary
>>
>> On Oct 29, 2013, at 7:41 PM, Li Dong <dongli@lasg.iap.ac.cn> wrote:
>>
>>> Dear NCL team,
>>>
>>> After solve the linking problem for the EEMD codes, I tried to test it in NCL. I printed the result in the wrapper function before return, and it is correct. But when I printed it in NCL script, there are undefined values as:
>>>
>>> CORRECT ONE (printed in wrapper function):
>>> Mode 0:
>>> 0.000000
>>> 0.642792
>>> 0.984796
>>> 0.866018
>>> 0.342024
>>> -0.342024
>>> -0.866018
>>> -0.984796
>>> -0.642792
>>> 0.000000
>>>
>>> WRONG ONE (printed in NCL script):
>>> (0) -9.671524e+09
>>> (1) 4.574539e-41
>>> (2) -9.671574e+09
>>> (3) 4.574539e-41
>>> (4) -9.671623e+09
>>> (5) 4.574539e-41
>>> (6) -9.671672e+09
>>> (7) 4.574539e-41
>>> (8) 0
>>> (9) 0.6427915
>>>
>>> The return part of my wrapper function is:
>>>
>>> ng_size_t dimsizes_imf[2] = { nm, ns };
>>>
>>> return NclReturnValue(
>>> (void*)imf,
>>> 2,
>>> dimsizes_imf,
>>> NULL,
>>> NCL_float,
>>> 0
>>> );
>>>
>>> In this case, nm = 4, ns = 10, and imf is “float **". Where is wrong? Thank you in advance!
>>>
>>> Best regards,
>>>
>>> Li
>>> _______________________________________________
>>> ncl-talk mailing list
>>> List instructions, subscriber options, unsubscribe:
>>> http://mailman.ucar.edu/mailman/listinfo/ncl-talk
>>
>

_______________________________________________
ncl-talk mailing list
List instructions, subscriber options, unsubscribe:
http://mailman.ucar.edu/mailman/listinfo/ncl-talk
Received on Wed Oct 30 14:49:31 2013

This archive was generated by hypermail 2.1.8 : Fri Nov 01 2013 - 08:58:14 MDT