Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Thread-Safe Implementation #157

Open
wants to merge 3 commits into
base: master
Choose a base branch
from

Conversation

ahayashi
Copy link

Add thread-safety to XACC/QCOR (Experimental). We introduce _XACC_MUTEX macro in xacc.hpp to turn on/off the feature (default is OFF). When the macro is ON, only a single thread can execute the following routines by using eit
her std::mutex or std::recursive_mutex:

  • User-facing API routines

    • createObjectiveFunction() (qcor::__internal__::get_objective())
    • createOptimizer()
  • Compiler-related modules

    • Syntax Handler
      • QuantumKernel::operator()
      • QuantumKernel::~QuantumKernel()
    • QJIT
      • QJIT::QJIT()
      • QJIT::jit_compile()
      • QJIT::write_cache()

Also, regardless of the macro, the VQEObjective class is now xacc::Cloneable.

Add the following test files to test multi-thread execution. It is worth noting that, when the macro is OFF, these test programs are executed sequentially.

  • examples/simple/bell_threaded.cpp
  • examples/simple/simple-objective-function-async.cpp
  • examples/simple/simple-objective-function-threaded.cpp
  • examples/qpu_lambda/deuteron_threaded.cpp
  • examples/qpu_lambda/deuteron_vqe_threaded.cpp
  • examples/qpu_lambda/deuteron_vqe_obj_func_threaded.cpp
  • examples/qpu_lambda/lambda_test_bell_threaded.cpp

@ahayashi ahayashi force-pushed the thread_safe_impl branch 3 times, most recently from 9eafcb7 to bb22d14 Compare June 30, 2021 18:56
@ahayashi
Copy link
Author

Hi @amccaskey,

I've just updated XACC's cmake/xacc-config.cmake.in and cmake/xacc_config.hpp.in so QCOR can detect whether the _XACC_MUTEX (C macro) and XACC_MULTI_THREDED (CMAKE variable) are defined (eclipse/xacc@d51b6dc).

Having that said, I'd like to get your advice on how to use those variables in QCOR.

Currently, many of my thread-safe implementations do something like this to check if _XACC_MUTEX is defined:

#include "xacc_config.hpp" // define/undef _XACC_MUTEX
#ifdef _XACC_MUTEX
#include <mutex>
#include <thread>
#endif
...
#ifdef _XACC_MUTEX
std::cout << "_XACC_MUTEX is defined: multi-threding execution" << std::endl;
#endif

I was wondering if I should keep this pattern or somehow update it. One alternative implementation I came up with was, like the XACC part, to update QCOR's qcor_config.hpp.in and let CMake define _QCOR_MUTEX if _XACC_MULTI_THREADED (set by XACC's CMake) is defined:

#include "qcor_config.hpp" // define/undef _QCOR_MUTEX
#ifdef _QCOR_MUTEX
#include <mutex>
#include <thread>
#endif
...
#ifdef _QCOR_MUTEX
std::cout << "_QCOR_MUTEX is defined: multi-threding execution" << std::endl;
#endif

Which one would you prefer? Please let me know if you have any other suggestions.

@amccaskey
Copy link
Collaborator

Hey akihiro, I like your idea of setting up a QCOR_MUTEX variable based on the upstream value of the xacc one

@ahayashi
Copy link
Author

Hey @amccaskey, sure I'll update the PR accordingly.

Add thread-safety to XACC/QCOR (Experimental). We introduce `_XACC_MUTEX` macro in `xacc.hpp` to turn on/off the feature (default is OFF). When the macro is ON, only a single thread can execute the following routines by using either `std::mutex` or `std::recursive_mutex`:

- User-facing API routines
   - `createObjectiveFunction()` (`qcor::__internal__::get_objective()`)
   - `createOptimizer()`

- Compiler-related modules
   - Syntax Handler
       - `QuantumKernel::operator()`
       - `QuantumKernel::~QuantumKernel()`
   - QJIT
      -  `QJIT::QJIT()`
      -  `QJIT::jit_compile()`
      -  `QJIT::write_cache()`

Also, regardless of the macro, the `VQEObjective` class is now `xacc::Cloneable`.

Add the following test files to test multi-thread execution

- `examples/simple/bell_threaded.cpp`
- `examples/simple/simple-objective-function-async.cpp`
- `examples/simple/simple-objective-function-threaded.cpp`
- `examples/qpu_lambda/deuteron_threaded.cpp`
- `examples/qpu_lambda/deuteron_vqe_threaded.cpp`
- `examples/qpu_lambda/deuteron_vqe_obj_func_threaded.cpp`
- `examples/qpu_lambda/lambda_test_bell_threaded.cpp`

Signed-off-by: Akihiro Hayashi <ahayashi@gatech.edu>
…ULTI_THREADED

Signed-off-by: Akihiro Hayashi <ahayashi@gatech.edu>
Remove deuteron_threaded.cpp from ctest

Signed-off-by: Akihiro Hayashi <ahayashi@gatech.edu>
@ahayashi
Copy link
Author

@amccaskey, I think I've incorporated all the requested changes and updated the PR.

One thing to note is that I added deuteron_threaded.cpp, which is a threaded version of deuteron.cpp, a while ago. However, since deuteron.cpp cannot be compiled by recent versions of QCOR, I didn't include it in ctest.

Please let me know if you have any further requests. I'll be happy to work on that.

Akihiro

@amccaskey
Copy link
Collaborator

@ahayashi I just reviewed this. I think it looks fine. I do have one request before we pull it. I'm interested in demonstrating why one would need multithreaded qcor.

I think it would be helpful if you put together an example that tries to use multiple threads to solve a single problem in less time than you could have sequentially. Of course, let's just use QPP as a simulation backend, but maybe we could create an OptFunction that spawns off multiple threads, each thread computing the expected value of a single term in a Hamiltonian, with a join and sync on the values, summed and returned for the Optimizer. Would be nice to profile the runtime and show a speedup.

Also can we show multi-threaded execution on the IBM backend? Multiple threads submitting jobs to be queued and executed.

@ahayashi
Copy link
Author

ahayashi commented Aug 6, 2021

@amccaskey, thanks for reviewing this!

Yes, the OptFunction example sounds good to me. Let me create such an example and add it.

Re. the IBM backend, while I've been only focusing on the QPP backend, yes, I'll be happy to work on supporting the IBM backend.

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.

2 participants