3
$\begingroup$

Local file demo.c have some library link API example, such as:

example 1:

/* Gets the subpart of the input tensor starting at the I0 th position */
DLLEXPORT int demo_TI_T(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    MTensor T0, T1 = 0;
    mint I0;
    int err = LIBRARY_NO_ERROR;

    T0 = MArgument_getMTensor(Args[0]);
    I0 = MArgument_getInteger(Args[1]);
    err = libData->MTensor_getMTensor(T0, &I0, 1, &T1);
    MArgument_setMTensor(Res, T1);
    return err;
}

Try to call:

lis = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
fun = LibraryFunctionLoad["demo.dll", "demo_TI_T", {{Integer, 1}, Integer}, {Integer, 1}]
fun[lis, 1, 2]

I will get an error information like: enter image description here

example 2:

/* Sets the I0 th element in T0 to its value in T1 */
DLLEXPORT int demo_TTI_T(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    MTensor T0, T1;
    mint I0;
    int err = LIBRARY_NO_ERROR;

    T0 = MArgument_getMTensor(Args[0]);
    T1 = MArgument_getMTensor(Args[1]);
    I0 = MArgument_getInteger(Args[2]);
    err = libData->MTensor_setMTensor(T0, T1, &I0, 1);
    MArgument_setMTensor(Res, T0);
    return err;
}

Try to call:

lis1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
lis2 = {8, 9, 3, 7, 1, 8, 6};
fun = LibraryFunctionLoad["demo.dll", 
  "demo_TTI_T", {{Integer, 1}, {Integer, 1}, Integer}, {Integer, 1}]
fun[lis1, lis2, 4]

I will get an error information like: enter image description here

example 3

/* Sets the element in the I0,I1 position in T0 to its value in T1, returning T0 */
DLLEXPORT int demo_TTII_T(WolframLibraryData libData, mint Argc, MArgument *Args, MArgument Res) {
    MTensor T0, T1;
    mint I0, I1;
    mint pos[2];
    int err = LIBRARY_NO_ERROR;

    T0 = MArgument_getMTensor(Args[0]);
    T1 = MArgument_getMTensor(Args[1]);
    I0 = MArgument_getInteger(Args[2]);
    I1 = MArgument_getInteger(Args[3]);
    pos[0] = I0;
    pos[1] = I1;
    err = libData->MTensor_setMTensor(T0, T1, pos, 2);
    MArgument_setMTensor(Res, T0);
    return err;
}

Try to call:

lis1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
lis2 = {8, 9, 3, 7, 1, 8, 6};
fun = LibraryFunctionLoad["demo.dll", "demo_TTII_T", {{Integer, 1}, {Integer, 1}, Integer, 
   Integer}, {Integer, 1}]
fun[lis1, lis2, 3, 5]

I will get an error information like: enter image description here

Is there any change in verion 13.1? But I didn't see any mention in the document. Or did I make any mistake?

$\endgroup$
2
  • 1
    $\begingroup$ Please include the exact error messages instead of saying "I get an error". That forces people to run the code before they can decide whether they can understand the error and even help you. Also, if you get an error that no one else is getting, "I get an error" is even less helpful $\endgroup$
    – Lukas Lang
    Aug 9 at 12:01
  • $\begingroup$ @LukasLang Hi, I omitted that information just don't want to make the layout chaos, if you feel the need I can add $\endgroup$
    – yode
    Aug 9 at 14:08

1 Answer 1

9
$\begingroup$

You are simply misinterpreting the examples I think:

Example 1:

Reading the error message (please post them directly in the question in future)

fun[lis, 1, 2]
(* LibraryFunction::cfct: Number of arguments 3 does not match the length 2 of the argument template. *)
(* LibraryFunction[demo.dll", "demo_TI_T", {{Integer, 1}, Integer}, {Integer, 1}][{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, 1, 2] *)

This is fairly clear. You are supplying 3 arguments, but you define the function to take 2. Fixing this, we get the next error:

fun[lis, 1]
(* LibraryFunction::reserrr: The result had rank 0 instead of the specified rank 1. *)
(* $Failed *)

Here it helps to read the documentation of MTensor_getMTensor:

int MTensor_getMTensor(MTensor t,mint*pos,mint numpos,MTensor*pres)

gets a subtensor element from an MTensor.

So what this function is doing is getting the I0'th element of T0. With this in mind, we redefine the function to take a rank-2 tensor and return a rank-1 tensor:

lis = Partition[Range@12, 3];
fun = LibraryFunctionLoad["demo.dll", 
   "demo_TI_T", {{Integer, 2}, Integer}, {Integer, 1}];
fun[lis, 1]
(* {1, 2, 3} *)

Example 2:

The original error:

fun[lis1, lis2, 4]
(* LibraryFunction::rnkerr: An error caused by inconsistent tensor rank was encountered evaluating the function demo_TTI_T. *)
(* LibraryFunctionError["LIBRARY_RANK_ERROR", 2] *)

Reading the documentation of MTensor_setMTensor, it is clear that it sets the I0'th element of T0 to be T1 (despite the misleading code comment):

lis1 = Partition[Range@12, 3];
lis2 = {8, 9, 3};
fun = LibraryFunctionLoad["demo.dll", 
   "demo_TTI_T", {{Integer, 2}, {Integer, 1}, Integer}, {Integer, 
    2}];
fun[lis1, lis2, 4]
(* {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {8, 9, 3}} *)

Example 3:

This is almost the same as Example 2, but with a rank-3 input and a two-level position. Original error:

lis1 = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
lis2 = {8, 9, 3, 7, 1, 8, 6};
fun = LibraryFunctionLoad["demo.dll", 
   "demo_TTII_T", {{Integer, 1}, {Integer, 1}, Integer, 
    Integer}, {Integer, 1}];
fun[lis1, lis2, 3, 5]
(* LibraryFunction::rnkerr: An error caused by inconsistent tensor rank was encountered evaluating the function demo_TTII_T. *)
(* LibraryFunctionError["LIBRARY_RANK_ERROR", 2] *)

A correct call:

lis1 = Partition[Partition[Range@27, 3], 3];
lis2 = {8, 9, 3}; fun = 
 LibraryFunctionLoad["demo.dll", 
  "demo_TTII_T", {{Integer, 3}, {Integer, 1}, Integer, 
   Integer}, {Integer, 3}];
fun[lis1, lis2, 1, 2]
(* {{{1, 2, 3}, {8, 9, 3}, {7, 8, 9}}, {{10, 11, 12}, {13, 14, 
   15}, {16, 17, 18}}, {{19, 20, 21}, {22, 23, 24}, {25, 26, 27}}} *)
$\endgroup$

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.