Skip to content

Setup examples/tutorials for the C API - #313

Open
Luthaf wants to merge 5 commits into
metatensor:metatomic-corefrom
Luthaf:setup-examples
Open

Setup examples/tutorials for the C API#313
Luthaf wants to merge 5 commits into
metatensor:metatomic-corefrom
Luthaf:setup-examples

Conversation

@Luthaf

@Luthaf Luthaf commented Sep 2, 2026

Copy link
Copy Markdown
Member

This re-opens #305 which was merged without review.

This PR uses sphinx-gallery ability to parse non-Python examples to make tutorial for the C API. The corresponding code is tested separately, since sphinx does not know how to run it.

Contributor (creator of pull-request) checklist

  • Tests updated (for new features and bugfixes)?
  • Documentation updated (for new features)?
  • Issue referenced (for PRs that solve an issue)?

Reviewer checklist

  • CHANGELOG updated with public API or any other important changes?

@Luthaf
Luthaf requested a review from EricBoittier September 2, 2026 12:02

@EricBoittier EricBoittier left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me

@EricBoittier EricBoittier left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review of code up to and including "1-create-system.c"

Follow-up PR for other examples (e.g. models, plugins, engines, etc) to come

mta_system_free(system);
return EXIT_FAILURE;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if (status != MTA_SUCCESS) {
    fprintf(stderr, "failed to get system size\n");
    mta_system_free(system);
    return EXIT_FAILURE;
}
printf("created system with %lu atoms\n", (unsigned long)size);

mta_string_t length_unit = NULL;
status = mta_system_get_length_unit(system, &length_unit);
if (status != MTA_SUCCESS) {
    fprintf(stderr, "failed to get length unit\n");
    mta_system_free(system);
    return EXIT_FAILURE;
}
printf("length unit: %s\n", mta_string_view(length_unit));
mta_string_free(length_unit);

// %%
//
// Query types, positions, cell, and PBC
// -------------------------------------
//
// :c:func:`mta_system_get_data` returns a **borrowed** DLPack view of the
// requested data. You must call the tensor's ``deleter`` when you are done;
// do not modify the underlying buffer.

DLManagedTensorVersioned* data = NULL;

status = mta_system_get_data(system, MTA_SYSTEM_DATA_TYPES, &data);
if (status != MTA_SUCCESS) {
    fprintf(stderr, "failed to get types\n");
    mta_system_free(system);
    return EXIT_FAILURE;
}
int32_t* types_view = (int32_t*)((char*)data->dl_tensor.data + data->dl_tensor.byte_offset);
printf("types:");
for (uintptr_t i = 0; i < size; i++) {
    printf(" %d", types_view[i]);
}
printf("\n");
data->deleter(data);```

//Consider adding examples for other queries


// %%

return EXIT_SUCCESS; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something like an "expected output" block could be nice to have, eg:

double* positions_view = (double*)((char*)data->dl_tensor.data + data->dl_tensor.byte_offset);
printf("positions:\n");
for (uintptr_t i = 0; i < size; i++) {
    printf("  %.3f %.3f %.3f\n",
           positions_view[3 * i + 0],
           positions_view[3 * i + 1],
           positions_view[3 * i + 2]);
}
data->deleter(data);

status = mta_system_get_data(system, MTA_SYSTEM_DATA_CELL, &data);
if (status != MTA_SUCCESS) {
    fprintf(stderr, "failed to get cell\n");
    mta_system_free(system);
    return EXIT_FAILURE;
}
double* cell_view = (double*)((char*)data->dl_tensor.data + data->dl_tensor.byte_offset);
printf("cell:\n");
for (int i = 0; i < 3; i++) {
    printf("  %.3f %.3f %.3f\n",
           cell_view[3 * i + 0],
           cell_view[3 * i + 1],
           cell_view[3 * i + 2]);
}
data->deleter(data);

status = mta_system_get_data(system, MTA_SYSTEM_DATA_PBC, &data);
if (status != MTA_SUCCESS) {
    fprintf(stderr, "failed to get pbc\n");
    mta_system_free(system);
    return EXIT_FAILURE;
}
uint8_t* pbc_view = (uint8_t*)((char*)data->dl_tensor.data + data->dl_tensor.byte_offset);
printf("pbc: %s %s %s\n",
       pbc_view[0] ? "true" : "false",
       pbc_view[1] ? "true" : "false",
       pbc_view[2] ? "true" : "false");
data->deleter(data);

// %%
//
// Running this program prints::
//
//     created system with 4 atoms
//     length unit: Angstrom
//     types: 1 1 6 6
//     positions:
//       0.000 0.000 0.000
//       0.500 0.500 0.000
//       0.500 0.000 0.500
//       0.000 0.500 0.500
//     cell:
//       1.000 0.000 0.000
//       0.000 1.000 0.000
//       0.000 0.000 1.000
//     pbc: true true true

Comment thread examples/c/README.rst
.. _c-tutorials:

C API tutorials
===============

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a warning about WIP until the C api is finalized?


.. danger::

    This section is a **work in progress (WIP)**. The examples and wording may
    change without notice.

Comment thread docs/src/examples/index.rst Outdated
Comment on lines +27 to +28
// You should also explore the corresponding documentation in the DLPack header
// file, which describes the full DLPack API and options.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Worth adding a link to the dlpack header or documentation?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread examples/c/1-create-system.c Outdated
// Free the system once it is no longer needed. The DLPack tensors have already
// been consumed by ``mta_system_create`` and must not be freed again.

mta_system_free(system);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check the returned mta_status_t for good measure?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree, something like

status = mta_system_free(system);
if (status != MTA_SUCCESS) {
    fprintf(stderr, "failed to free system memory\n");
    return EXIT_FAILURE;
 };

Comment thread docs/src/examples/index.rst Outdated
EricBoittier and others added 3 commits September 3, 2026 16:02
Co-authored-by: Rocco Meli <r.meli@bluemail.ch>
Co-authored-by: Rocco Meli <r.meli@bluemail.ch>
Co-authored-by: Rocco Meli <r.meli@bluemail.ch>
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

Successfully merging this pull request may close these issues.

3 participants