Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions metatomic-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ metatensor = { version = "0.3.0" }
once_cell = "1"
dlpk = "0.3"
json = "0.12"
libloading = "0.8"


[build-dependencies]
Expand Down
42 changes: 41 additions & 1 deletion metatomic-core/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ fn main() {
config.documentation_style = cbindgen::DocumentationStyle::Doxy;
config.line_endings = cbindgen::LineEndingStyle::LF;
config.autogen_warning = Some(generated_comment.into());
config.includes.push("metatensor.h".into());
config.sys_includes.push("stdio.h".into());
config.sys_includes.push("metatensor.h".into());
config.includes.push("metatomic/version.h".into());

config.export = cbindgen::ExportConfig {
Expand All @@ -33,6 +34,45 @@ fn main() {
};
config.after_includes = Some("

#ifndef MTA_EXPORT
#if defined(_WIN32) || defined(__CYGWIN__)
#define MTA_EXPORT __declspec(dllexport)
#else
#define MTA_EXPORT __attribute__((visibility(\"default\")))
#endif
#endif

#ifndef MTA_EXTERN_C
#ifdef __cplusplus
#define MTA_EXTERN_C extern \"C\"
#else
#define MTA_EXTERN_C
#endif
#endif

/**
* Define the exported plugin entry points.
*
* This macro should be used once in each plugin shared library with a
* `mta_plugin_t` expression. It exports the plugin ABI version and a
* registration function used by `mta_load_plugin`.
*/
#define MTA_REGISTER_PLUGIN(register_fn_name, ...) \\
MTA_EXTERN_C MTA_EXPORT mta_status_t mta_plugin_init(int abi, void *data) { \\
if (abi != MTA_ABI_VERSION) { \\
char message[256]; \\
snprintf(message, sizeof(message), \\
\"Metatomic plugin ABI version mismatch: expected %d, got %d\", \\
MTA_ABI_VERSION, abi \\
); \\
mta_set_last_error(message, \"MTA_REGISTER_PLUGIN\", NULL, NULL); \\
return MTA_INVALID_PARAMETER_ERROR; \\
} \\
mta_status_t (*register_fn_name)(mta_plugin_t) = (mta_status_t (*)(mta_plugin_t))data; \\
__VA_ARGS__; \\
return MTA_SUCCESS; \\
}

/** Heap allocated storage for mta_string_t */
typedef struct mta_opaque_string_t mta_opaque_string_t;".into());

Expand Down
133 changes: 120 additions & 13 deletions metatomic-core/include/metatomic.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,59 @@
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include "metatensor.h"
#include <stdio.h>
#include <metatensor.h>
#include "metatomic/version.h"


#ifndef MTA_EXPORT
#if defined(_WIN32) || defined(__CYGWIN__)
#define MTA_EXPORT __declspec(dllexport)
#else
#define MTA_EXPORT __attribute__((visibility("default")))
#endif
#endif

#ifndef MTA_EXTERN_C
#ifdef __cplusplus
#define MTA_EXTERN_C extern "C"
#else
#define MTA_EXTERN_C
#endif
#endif

/**
* Define the exported plugin entry points.
*
* This macro should be used once in each plugin shared library with a
* `mta_plugin_t` expression. It exports the plugin ABI version and a
* registration function used by `mta_load_plugin`.
*/
#define MTA_REGISTER_PLUGIN(register_fn_name, ...) \
MTA_EXTERN_C MTA_EXPORT mta_status_t mta_plugin_init(int abi, void *data) { \
if (abi != MTA_ABI_VERSION) { \
char message[256]; \
snprintf(message, sizeof(message), \
"Metatomic plugin ABI version mismatch: expected %d, got %d", \
MTA_ABI_VERSION, abi \
); \
mta_set_last_error(message, "MTA_REGISTER_PLUGIN", NULL, NULL); \
return MTA_INVALID_PARAMETER_ERROR; \
} \
mta_status_t (*register_fn_name)(mta_plugin_t) = (mta_status_t (*)(mta_plugin_t))data; \
__VA_ARGS__; \
return MTA_SUCCESS; \
}

/** Heap allocated storage for mta_string_t */
typedef struct mta_opaque_string_t mta_opaque_string_t;

/**
* TODO
* ABI version of the metatomic plugin interface.
*
* This increases anytime the plugin or model C API changes in a non backward
* compatible way. Plugins compiled with an incompatible ABI version will be
* rejected at registration time.
*/
#define MTA_ABI_VERSION 1

Expand All @@ -47,11 +91,10 @@ typedef enum mta_status_t {
*/
MTA_SERIALIZATION_ERROR = 3,
/**
* Status code indicating errors that come from callbacks provided by the user.
* The error message and arbitrary data can be stored using `mta_set_last_error`,
* and retrieved using `mta_last_error`.
* Status code used by plugins when a model is not supported by the
* current plugin
*/
MTA_CALLBACK_ERROR = 254,
MTA_MODEL_NOT_SUPPORTED_ERROR = 4,
/**
* Status code used when there is an internal error
*/
Expand Down Expand Up @@ -234,15 +277,41 @@ typedef struct mta_model_t {
} mta_model_t;

/**
* TODO
* A metatomic plugin definition.
*/
typedef struct mta_plugin_t {
/**
* TODO
* ABI version this plugin was compiled against, this should be set to
* `MTA_ABI_VERSION` when creating the plugin struct.
*/
int32_t abi_version;
/**
* Name of the plugin, as a null-terminated UTF-8 string. This is the name
* specified in `mta_load_model` when trying to load a model with a
* specific plugin. The name must be unique among all registered plugins.
*/
const char *name;
/**
* TODO
* Callback function to load a model. This function should try to load a
* model from `load_from` (which can be a file path, a model name, etc.)
* and a set of key/values options passed as a JSON string.
*
* If the plugin can load the model, it should fill `model` with a pointer
* to a valid `mta_model_t` struct and return `MTA_SUCCESS`. If the data in
* `load_from` does not correspond to a model supported by the plugin, it
* should return `MTA_MODEL_NOT_SUPPORTED_ERROR`. If an error occurs while
* loading the model, it should return another status code and save an
* error message with `mta_set_last_error`.
*
* @param load_from a null-terminated UTF-8 string describing where to load
* the model from (e.g. a file path, a model name, etc.). The interpretation
* of this string is up to the plugin.
* @param options_json a null-terminated UTF-8 string containing a set of
* string keys and string value options for loading the model.
* @param model output pointer to the loaded model. The caller takes ownership of
* the model and must unload it when the model is no longer needed.
* @return `MTA_SUCCESS` if the model was loaded successfully, `MTA_MODEL_NOT_SUPPORTED_ERROR`
* if the plugin can not load the model, or another status code if an error occurs.
*/
enum mta_status_t (*load_model)(const char *load_from,
const char *options_json,
Expand Down Expand Up @@ -445,17 +514,55 @@ enum mta_status_t mta_execute_model(struct mta_model_t model,
enum mta_status_t mta_format_metadata(const char *metadata, mta_string_t *printed);

/**
* TODO
* Register a plugin. This is passed as a callback to the `MTA_REGISTER_PLUGIN`
* macro, and should not be called directly by C or C++ plugin implementations.
*
* @param plugin the plugin to register
* @return `MTA_SUCCESS` if the plugin was registered successfully, or another
* status code if an error occurs. You can get more details about the error
* with `mta_last_error`.
*/
void mta_register_plugin(struct mta_plugin_t plugin);
enum mta_status_t mta_register_plugin(struct mta_plugin_t plugin);

/**
* TODO
* Load the shared library at `path` and register the plugin contained within.
*
* The library must export the symbols generated by the `MTA_REGISTER_PLUGIN`
* macro.
*
* @param path a null-terminated UTF-8 string containing the path to the plugin
* shared library
* @return `MTA_SUCCESS` if the plugin was loaded successfully, or another
* status code if an error occurs. You can get more details about the
* error with `mta_last_error`.
*/
enum mta_status_t mta_load_plugin(const char *path);

/**
* TODO
* Load a model from `load_from` with the given options.
*
* If `plugin_name` is a NULL pointer, metatomic will try to determine the
* correct plugin to use by checking the `load_from` parameter. If we can not
* determine the correct plugin, we then try to load the model with each
* registered plugin until one succeeds.
*
* If `plugin_name` is given, then we only try to load the model with the
* specified plugin, and return an error if the plugin can not load the model.
*
* @param plugin_name optional null-terminated UTF-8 string containing the name
* of the plugin to use for loading the model, or `NULL` to let metatomic
* search for a correct plugin
* @param load_from a null-terminated UTF-8 string describing where to load the
* model from (e.g. a file path, a model name, etc.). The interpretation
* of this string is up to the plugin.
* @param options_json a null-terminated UTF-8 string containing a set of string
* keys and string value options for loading the model. The interpretation
* of these options is up to the plugin.
* @param model output pointer to the loaded model. The caller takes ownership of
* the model and must unload it when the model is no longer needed.
* @return `MTA_SUCCESS` if the model was loaded successfully, or another
* status code if an error occurs. You can get more details about the
* error with `mta_last_error`.
*/
enum mta_status_t mta_load_model(const char *plugin_name,
const char *load_from,
Expand Down
2 changes: 1 addition & 1 deletion metatomic-core/src/c_api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,4 @@ mod model;
pub use self::model::mta_model_t;

mod plugin;
pub use self::plugin::{mta_plugin_t, mta_register_plugin, mta_load_model};
pub use self::plugin::{mta_plugin_t, mta_register_plugin, mta_load_plugin, mta_load_model};
15 changes: 15 additions & 0 deletions metatomic-core/src/c_api/model.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,21 @@ pub struct mta_model_t {
) -> mta_status_t>,
}

impl mta_model_t {
pub(crate) fn null() -> Self {
return mta_model_t {
data: std::ptr::null_mut(),
unload: None,
capabilities: None,
metadata: None,
supported_outputs: None,
requested_pair_lists: None,
requested_inputs: None,
execute_inner: None,
};
}
}

/// Execute a model to compute the requested outputs for a set of systems
///
/// This is the main entry point to run a model loaded through the C API. It
Expand Down
Loading
Loading