Skip to content

Commit

Permalink
Merge pull request #162 from MolSSI-MDI/plugins
Browse files Browse the repository at this point in the history
Fix bug when compiling without plugin support
  • Loading branch information
taylor-a-barnes authored Mar 15, 2024
2 parents 3765f1f + 9872d0d commit 2be2325
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 20 deletions.
23 changes: 19 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ jobs:
matrix:
platform: [ ubuntu-latest, macos-latest ]
mpilib: [null, mpich, openmpi]
plugins: [OFF, ON]

# The type of runner that the job will run on
runs-on: ${{ matrix.platform }}
Expand All @@ -47,9 +48,15 @@ jobs:
touch env.source
# Set MDI_TESTS, which defines which tests will be performed for this job
[ "${{ matrix.mpilib }}" == "" ] && echo 'export MDI_TESTS="not mpi"' >> env.source
[ "${{ matrix.mpilib }}" != "" ] && [ "${{ matrix.platform }}" == "macos-latest" ] && echo 'export MDI_TESTS="not mpi and not py_plug and not py_cxx_plug"' >> env.source
export MDI_TESTS_TEMP=""
[ "${{ matrix.mpilib }}" == "" ] && export MDI_TESTS_TEMP="not mpi"
[ "${{ matrix.mpilib }}" != "" ] && [ "${{ matrix.platform }}" == "macos-latest" ] && export MDI_TESTS_TEMP="not mpi and not py_plug and not py_cxx_plug"
# Ensure that plugins tests are not run if plugins are not enabled
[ "${{ matrix.plugins }}" == "OFF" ] && [ "${MDI_TESTS_TEMP}" == "" ] && export MDI_TESTS_TEMP="not plug"
[ "${{ matrix.plugins }}" == "OFF" ] && [ "${MDI_TESTS_TEMP}" != "" ] && export MDI_TESTS_TEMP="${MDI_TESTS_TEMP} and not plug"
echo "export MDI_TESTS=\"${MDI_TESTS_TEMP}\"" >> env.source
cat env.source
# Only custom build python on ubuntu
Expand Down Expand Up @@ -139,7 +146,7 @@ jobs:
run: |
source env.source
brew uninstall --ignore-dependencies gcc || true
brew install gcc || brew link --overwrite python@3.10
brew install gcc || brew link --overwrite python@3.12
- name: Install MPICH (MacOS)
if: matrix.platform == 'macos-latest' && matrix.mpilib == 'mpich'
Expand All @@ -153,10 +160,18 @@ jobs:
source env.source
brew install openmpi
- name: Create and activate a virtual environment (MacOS)
if: matrix.platform == 'macos-latest'
run: |
python3 -m venv venv
cat venv/bin/activate >> env.source
source env.source
- name: Install Pip dependencies (MacOS)
if: matrix.platform == 'macos-latest'
run: |
source env.source
source venv/bin/activate
python3 -m pip install --upgrade pip
[ ! "${{ matrix.mpilib }}" == "" ] && python3 -m pip install mpi4py
python3 -m pip install numpy
Expand All @@ -181,7 +196,7 @@ jobs:
export FC=gfortran
export CMAKE_COVERAGE_FLAGS=""
[ "${{ matrix.platform }}" == "ubuntu-latest" ] && export CMAKE_COVERAGE_FLAGS="-O0 -coverage"
cmake -Dtest_codes=ON -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_C_FLAGS="$CMAKE_COVERAGE_FLAGS" -DCMAKE_CXX_FLAGS="$CMAKE_COVERAGE_FLAGS" -DCMAKE_Fortran_FLAGS="$CMAKE_COVERAGE_FLAGS" ..
cmake -Dtest_codes=ON -Dplugins=${{ matrix.plugins }} -DCMAKE_INSTALL_PREFIX=./install -DCMAKE_C_FLAGS="$CMAKE_COVERAGE_FLAGS" -DCMAKE_CXX_FLAGS="$CMAKE_COVERAGE_FLAGS" -DCMAKE_Fortran_FLAGS="$CMAKE_COVERAGE_FLAGS" ..
make VERBOSE=1
make install
ls
Expand Down
71 changes: 71 additions & 0 deletions MDI_Library/mdi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2220,6 +2220,7 @@ int MDI_Set_Execute_Command_Func(int (*generic_command)(const char*, MDI_Comm, v
* Function pointer to the generic execute_command function
*/
int MDI_Set_execute_command_func(int (*generic_command)(const char*, MDI_Comm, void*), void* class_object) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand Down Expand Up @@ -2252,10 +2253,15 @@ int MDI_Set_execute_command_func(int (*generic_command)(const char*, MDI_Comm, v
}

return 0;
#else
mdi_error("MDI_Set_execute_command_func was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


int MDI_Set_plugin_state(void* state) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;
ret = mdi_debug("[MDI:MDI_Set_plugin_state] Start\n");
if ( ret != 0 ) {
Expand All @@ -2270,6 +2276,10 @@ int MDI_Set_plugin_state(void* state) {
}

return library_set_state(state);
#else
mdi_error("MDI_Set_plugin_state was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


Expand All @@ -2279,7 +2289,12 @@ int MDI_Set_plugin_state(void* state) {
*
*/
int MDI_Set_plugin_state_internal(void* state) {
#if _MDI_PLUGIN_SUPPORT == 1
return library_set_state(state);
#else
mdi_error("MDI_Set_plugin_state_internal was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


Expand Down Expand Up @@ -2314,6 +2329,7 @@ int MDI_Get_Current_Code() {
*
*/
int MDI_Plugin_get_argc(int* argc_ptr) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand All @@ -2328,13 +2344,18 @@ int MDI_Plugin_get_argc(int* argc_ptr) {
}
*argc_ptr = *this_code->plugin_argc_ptr;
return 0;
#else
mdi_error("MDI_Plugin_get_argc was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


/*! \brief Get plugin_argv
*
*/
int MDI_Plugin_get_argv(char*** argv_ptr) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand All @@ -2349,13 +2370,18 @@ int MDI_Plugin_get_argv(char*** argv_ptr) {
}
*argv_ptr = *this_code->plugin_argv_ptr;
return 0;
#else
mdi_error("MDI_Plugin_get_argv was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


/*! \brief Get plugin_unedited_options
*
*/
int MDI_Plugin_get_args(char** args_ptr) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand All @@ -2370,13 +2396,18 @@ int MDI_Plugin_get_args(char** args_ptr) {
}
*args_ptr = *this_code->plugin_unedited_options_ptr;
return 0;
#else
mdi_error("MDI_Plugin_get_args was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


/*! \brief Get a specific element from plugin_argv
*
*/
int MDI_Plugin_get_arg(int index, char** arg_ptr) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand All @@ -2399,16 +2430,25 @@ int MDI_Plugin_get_arg(int index, char** arg_ptr) {
}
*arg_ptr = (*this_code->plugin_argv_ptr)[index];
return 0;
#else
mdi_error("MDI_Plugin_get_arg was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


/*! \brief Get the Python plugin MPI communicator
*
*/
int MDI_Get_python_plugin_mpi_world_ptr(void** python_plugin_mpi_world_ptr_ptr, void* state_in) {
#if _MDI_PLUGIN_SUPPORT == 1
plugin_shared_state* this_state = (plugin_shared_state*) state_in;
*python_plugin_mpi_world_ptr_ptr = this_state->mpi_comm_ptr;
return 0;
#else
mdi_error("MDI_Get_python_plugin_mpi_world_ptr was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


Expand Down Expand Up @@ -2587,6 +2627,7 @@ int MDI_Set_Mpi4py_Barrier_Callback(int (*mpi4py_barrier)(int)) {
* Function pointer to the launch_plugin callback
*/
int MDI_Set_Launch_Plugin_Callback(int (*launch_plugin)(void*, void*, void*, int)) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand All @@ -2597,6 +2638,11 @@ int MDI_Set_Launch_Plugin_Callback(int (*launch_plugin)(void*, void*, void*, int
}
this_code->py_launch_plugin_callback = launch_plugin;
return 0;
#else
// This function is automatically called when Python codes call MDI_Init
// We don't want to throw an error message here; simply return
return 0;
#endif
}


Expand All @@ -2608,9 +2654,14 @@ int MDI_Set_Launch_Plugin_Callback(int (*launch_plugin)(void*, void*, void*, int
* Language of the plugin
*/
int MDI_Set_plugin_language(int language, void* plugin_state) {
#if _MDI_PLUGIN_SUPPORT == 1
plugin_shared_state* this_state = (plugin_shared_state*) plugin_state;
this_state->engine_language = language;
return 0;
#else
mdi_error("MDI_Set_plugin_language was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


Expand All @@ -2622,6 +2673,7 @@ int MDI_Set_plugin_language(int language, void* plugin_state) {
* Execute command callback
*/
int MDI_Set_language_execute_command(int (*execute_command)(void*, MDI_Comm, void*)) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand Down Expand Up @@ -2651,6 +2703,10 @@ int MDI_Set_language_execute_command(int (*execute_command)(void*, MDI_Comm, voi
}

return 0;
#else
mdi_error("MDI_Set_language_execute_command was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


Expand All @@ -2665,6 +2721,7 @@ int MDI_Set_language_execute_command(int (*execute_command)(void*, MDI_Comm, voi
* MDI communicator
*/
int MDI_Get_language_execute_command(MDI_Execute_command_callback_t* language_execute_command, MDI_Comm comm) {
#if _MDI_PLUGIN_SUPPORT == 1
communicator* this_comm;
int ret = get_communicator(codes.current_key, comm, &this_comm);
if ( ret != 0 ) {
Expand All @@ -2674,6 +2731,10 @@ int MDI_Get_language_execute_command(MDI_Execute_command_callback_t* language_ex
library_data* libd = (library_data*) this_comm->method_data;
*language_execute_command = libd->shared_state->execute_command;
return 0;
#else
mdi_error("MDI_Get_language_execute_command was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


Expand All @@ -2687,6 +2748,7 @@ int MDI_Get_language_execute_command(MDI_Execute_command_callback_t* language_ex
* MDI communicator
*/
int MDI_Get_language_driver_callback(MDI_Driver_node_callback_f90_t* language_driver_callback) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand All @@ -2697,6 +2759,10 @@ int MDI_Get_language_driver_callback(MDI_Driver_node_callback_f90_t* language_dr
}
*language_driver_callback = this_code->driver_callback_f90;
return 0;
#else
mdi_error("MDI_Get_language_driver_callback was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}


Expand All @@ -2708,6 +2774,7 @@ int MDI_Get_language_driver_callback(MDI_Driver_node_callback_f90_t* language_dr
* Driver callback
*/
int MDI_Set_language_driver_callback(MDI_Driver_node_callback_f90_t callback) {
#if _MDI_PLUGIN_SUPPORT == 1
int ret;

code* this_code;
Expand All @@ -2718,4 +2785,8 @@ int MDI_Set_language_driver_callback(MDI_Driver_node_callback_f90_t callback) {
}
this_code->driver_callback_f90 = callback;
return 0;
#else
mdi_error("MDI_Set_language_driver_callback was called, but this build of the MDI Library was built without plugin support.");
return 1;
#endif
}
5 changes: 0 additions & 5 deletions tests/MDI_Test_Codes/engine_cxx/engine_cxx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,6 @@ int initialize_mdi(MDI_Comm* comm_ptr) {
// Connect to the driver
MDI_Accept_communicator(comm_ptr);

// Create the execute_command pointer
int (*generic_command)(const char*, MDI_Comm, void*) = execute_command;
void* engine_obj;
MDI_Set_execute_command_func(generic_command, engine_obj);

return 0;
}

Expand Down
13 changes: 6 additions & 7 deletions tests/MDI_Test_Codes/engine_f90/mdi_implementation.f90
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ FUNCTION MDI_Plugin_init_engine_f90(plugin_state) bind ( C, name="MDI_Plugin_ini
CHARACTER(LEN=1024) :: option
CHARACTER(LEN=1024) :: mdi_options
LOGICAL :: mdi_options_found
PROCEDURE(execute_command), POINTER :: generic_command => null()
TYPE(C_PTR) :: class_obj
generic_command => execute_command

CALL MDI_Set_plugin_state(plugin_state, ierr)

Expand All @@ -43,6 +46,9 @@ FUNCTION MDI_Plugin_init_engine_f90(plugin_state) bind ( C, name="MDI_Plugin_ini
! Perform one-time operations required to establish a connection with the driver
CALL initialize_mdi()

! Set the generic execute_command function
CALL MDI_Set_execute_command_func(c_funloc(generic_command), class_obj, ierr)

! Respond to commands from the driver
CALL respond_to_commands()

Expand All @@ -53,10 +59,6 @@ END FUNCTION MDI_Plugin_init_engine_f90
SUBROUTINE initialize_mdi()
INTEGER :: ierr, role

PROCEDURE(execute_command), POINTER :: generic_command => null()
TYPE(C_PTR) :: class_obj
generic_command => execute_command

! Confirm that the code is being run as an ENGINE
call MDI_Get_role(role, ierr)
IF ( role .ne. MDI_ENGINE ) THEN
Expand All @@ -80,9 +82,6 @@ SUBROUTINE initialize_mdi()
! Connct to the driver
CALL MDI_Accept_communicator(comm, ierr)

! Set the generic execute_command function
CALL MDI_Set_execute_command_func(c_funloc(generic_command), class_obj, ierr)

END SUBROUTINE initialize_mdi


Expand Down
9 changes: 5 additions & 4 deletions tests/MDI_Test_Codes/engine_py/engine_py.py
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def execute_command(command, comm, self):

class MDIEngine:

def __init__(self):
def __init__(self, is_plugin = False):
self.exit_flag = False

# MPI variables
Expand Down Expand Up @@ -98,7 +98,8 @@ def __init__(self):
mdi.MDI_Register_Callback("@FORCES",">FORCES")

# Set the generic execute_command function
mdi.MDI_Set_Execute_Command_Func(execute_command, self)
if is_plugin:
mdi.MDI_Set_Execute_Command_Func(execute_command, self)

# Connect to the driver
self.comm = mdi.MDI_Accept_Communicator()
Expand All @@ -117,14 +118,14 @@ def MDI_Plugin_init_engine_py(plugin_state):

mdi.MDI_Set_plugin_state(plugin_state)

engine = MDIEngine()
engine = MDIEngine(is_plugin = True)
engine.run()

def MDI_Plugin_open_engine_py(plugin_state):

mdi.MDI_Set_plugin_state(plugin_state)

engine = MDIEngine()
engine = MDIEngine(is_plugin = True)

if __name__== "__main__":
mdi.MDI_Init(sys.argv[2])
Expand Down

0 comments on commit 2be2325

Please sign in to comment.