5
$\begingroup$

Recently, I have rewritten pure Wolfram Language implementation CAGDBSplineSurface[] with C. Below is main LibraryLink code:

LibraryLink Code

#include "WolframLibrary.h"

/************************************************************************/
/*            BSplineSurface(P,U,V,p,q,u,v)                             */
/************************************************************************/ 
DLLEXPORT int BSplineSurface(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    /*define the argument-variable*/
    MTensor tensor_P, tensor_U, tensor_V;
    mreal *P, *U, *V;
    mint p, q;
    mreal u, v;
    /*define the program-variable*/
    MTensor tensor_S;
    mreal *S;
    mint k;
    mint dims[1];
    int err;
    mint const *P_dims;
    mint c;
    /*assign the argument-value to argument-variable*/
    tensor_P = MArgument_getMTensor(Args[0]);
    P = libData->MTensor_getRealData(tensor_P);
    tensor_U = MArgument_getMTensor(Args[1]);
    U = libData->MTensor_getRealData(tensor_U);
    tensor_V = MArgument_getMTensor(Args[2]);
    V = libData->MTensor_getRealData(tensor_V);
    p = MArgument_getInteger(Args[3]);
    q = MArgument_getInteger(Args[4]);
    u = MArgument_getReal(Args[5]);
    v = MArgument_getReal(Args[6]);
    /*achieve the dimensions of the tensor*/
    P_dims = libData->MTensor_getDimensions(tensor_P);
    c = P_dims[2];
    /*build the tensor*/
    dims[0] = c;
    err = libData->MTensor_new(MType_Real, 1, dims, &tensor_S);
    S = libData->MTensor_getRealData(tensor_S);
    /*initialize the S vector*/
    for (k = 0; k <= c - 1; k++){
        S[k] = 0.0;
    }
    /*main implementation*/
    calc_bspline_surf(P, U, V, p, q, u, v, P_dims, S);
    /*return the result*/
    MArgument_setMTensor(Res, tensor_S);
    return LIBRARY_NO_ERROR; 
}

However, when I compiled it to dll file, it always caused Mathematica crash.


Maybe someone would say this is just a C probelm, however, this time I have ran it in C and calc_bspline_surf() could return right result. I think it is a LibraryLink wrapper related question.

enter image description here

enter image description here

pts =
  {{{1, 1, 0.724003}, {1, 2, 0.583991}, {1, 3, 0.76682}, {1, 4, -0.739215}, {1, 5, 0.665493}}, 
  {{2, 1, -0.769059}, {2, 2, 0.549204}, {2, 3, 0.815537}, {2, 4, 0.512306}, {2, 5, 0.200062}}, 
  {{3, 1, -0.0984508}, {3, 2, 0.123631}, {3, 3, -0.938963}, {3, 4, 0.579558}, {3, 5, 0.612359}}, 
  {{4, 1, 0.377609}, {4, 2, 0.454769}, {4, 3, 0.87932}, {4, 4, -0.502242}, {4, 5, -0.603295}}, 
  {{5, 1, -0.645871}, {5, 2, -0.398243}, {5, 3, -0.510713}, {5, 4, -0.144209}, {5, 5, 0.145951}},
  {{6, 1, -0.334002}, {6, 2, -0.435887}, {6, 3, 0.182128}, {6, 4, 0.0293587}, {6, 5, 0.0583313}}};

f = BSplineFunction[pts];

Attachment

You could download the notebook via this link(thanks for happy fish help), and that Mathematica notebook contains the complete librarylink code.

$\endgroup$
  • $\begingroup$ Can't download the linked notebook even after login. $\endgroup$ – happy fish Jul 10 '16 at 7:07
  • $\begingroup$ They look the same...... $\endgroup$ – happy fish Jul 10 '16 at 11:21
  • 1
    $\begingroup$ I meant you typed "the difference between A and A" :) $\endgroup$ – happy fish Jul 10 '16 at 13:28
8
$\begingroup$

This is a incompatible pointer problem. Just change int const *dims to mint const *dims (a total of 2 places), and the function will give correct results.

My attempt to explain the difference:

(Since I don't use C, I may make mistakes. Feel free to edit, or if there are any serious mistakes, I will remove this paragraph)

mint refers to long in my system (maybe different on different system according to the typedef in WolframLibrary.h). A long integer occupies 32 bits while int occupies 16 bits (usually). A pointer originally a mint * would regard its address and its following 32 bits as the number. If it is forced to be converted to int *, the same address and its following 16 bits will be the number. This will cause a difference in results.

enter image description here

$\endgroup$
  • $\begingroup$ Some corrections: on every platform that I am aware of where Mathematica runs, int is 32-bit (never 16-bit). mint is a LibraryLink specific type which is 32-bit on 32-bit platforms and 64-bit on 64-bit platforms (signed in both cases). $\endgroup$ – Szabolcs Jul 10 '16 at 16:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.