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

ERROR: could not load symbol "p4est_iter_fside_array_index_int": The specified procedure could not be found. #99

Closed
Blumenkranz opened this issue Nov 21, 2023 · 10 comments

Comments

@Blumenkranz
Copy link

I got "ERROR: could not load symbol "p4est_iter_fside_array_index_int": The specified procedure could not be found." when I pass it a Ref(my_sc_array)

@JoshuaLampert
Copy link
Member

Can you provide an MWE please?

@Blumenkranz
Copy link
Author

Sure!

MPI.Init()
connectivity = p4est_connectivity_new_brick(2,2,0,0)
p4est = p4est_new_ext(MPI.COMM_WORLD, connectivity, 0, 1, 1,0,C_NULL, C_NULL)
p4est_iterate(p4est,C_NULL,C_NULL,C_NULL,@cfunction(show_face_info,Cvoid,(Ptr{p4est_iter_face_info_t},Ptr{Nothing})),C_NULL)
function show_face_info(info,data)
    ip = PointerWrapper(info)
    sides = Ptr{sc_array_t}(pointer_from_objref(Ref(ip.sides[])))
    side = p4est_iter_fside_array_index_int(sides,0)
    return nothing
end

@ranocha
Copy link
Member

ranocha commented Nov 22, 2023

It looks like it's missing since it's declared as static inline:

/** Return a pointer to a iter_face_side array element indexed by a int.
 */
/*@unused@*/
static inline p4est_iter_face_side_t *
p4est_iter_fside_array_index_int (sc_array_t * array, int it)
{
  P4EST_ASSERT (array->elem_size == sizeof (p4est_iter_face_side_t));
  P4EST_ASSERT (it >= 0 && (size_t) it < array->elem_count);

  return (p4est_iter_face_side_t *)
    (array->array + sizeof (p4est_iter_face_side_t) * (size_t) it);
}

See https://github.com/cburstedde/p4est/blob/aafb87d93e33dffe24d67533d56bc2f0cdb72605/src/p4est_iterate.h#L265-L276

I'm not sure whether it's really considered to be part of the public API of p4est either.

@Blumenkranz
Copy link
Author

The function is used in p4est's example:

static void
step3_upwind_flux (p4est_iter_face_info_t * info, void *user_data)
{
  int                 i, j;
  p4est_t            *p4est = info->p4est;
  step3_ctx_t        *ctx = (step3_ctx_t *) p4est->user_pointer;
  step3_data_t       *ghost_data = (step3_data_t *) user_data;
  step3_data_t       *udata;
  p4est_quadrant_t   *quad;
  double              vdotn = 0.;
  double              uavg;
  double              q;
  double              h, facearea;
  int                 which_face;
  int                 upwindside;
  p4est_iter_face_side_t *side[2];
  sc_array_t         *sides = &(info->sides);

  /* because there are no boundaries, every face has two sides */
  P4EST_ASSERT (sides->elem_count == 2);

  side[0] = p4est_iter_fside_array_index_int (sides, 0);
  side[1] = p4est_iter_fside_array_index_int (sides, 1);

See https://github.com/cburstedde/p4est/blob/master/example/steps/p4est_step3.c#L902
Can I achieve the same purpose with P4est.jl?

@ranocha
Copy link
Member

ranocha commented Nov 22, 2023

The function does not seem to be included in the dynamic library, so you can't call it. You could just write the code in Julia - the function definition doesn't look too long.

@sloede
Copy link
Member

sloede commented Nov 22, 2023

AFAICT, the function must not be exported from the dynamic library since it is marked static, which indicates internal linkage. That is, variables and functions marked as such may only be visible in the current translation unit. Thus, there is no way that this function may be called from the p4est library.

Why the p4est developers chose to implement it in such a way is different question. My first guess would be for performance reasons, but that only explains the inline, not the static part. Maybe @cburstedde could shed some light on this?

@Blumenkranz
Copy link
Author

I see. I'll write static functions in Julia. Thank you all for your help and time. And maybe we can add some explanation for these functions or just remove them from our API? The error can be confusing at the first time.

@ranocha
Copy link
Member

ranocha commented Nov 23, 2023

Yes, I definitely understand the confusion. Does Clang.jl have an option to skip static functions?

@cburstedde
Copy link

cburstedde commented Nov 23, 2023 via email

@sloede
Copy link
Member

sloede commented Nov 23, 2023

Thanks for the fast response and the explanation @cburstedde!

These functions do not have much use outside of the p4est C interface, so
I'm wondering if you might skip exporting them

Yes, that's a good suggestion. We are currently looking into whether this is feasible and how.

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

5 participants