From 4cb7a0da8a2e1c35ada2433eb5c295269f118761 Mon Sep 17 00:00:00 2001 From: Antoine Date: Thu, 22 Jun 2023 18:07:22 +0200 Subject: [PATCH] update mcs to semaphore --- .../maxmsp/mcs.nn_tilde/CMakeLists.txt | 7 ++ .../maxmsp/mcs.nn_tilde/mcs.nn_tilde.cpp | 73 +++++++++++++------ 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/src/frontend/maxmsp/mcs.nn_tilde/CMakeLists.txt b/src/frontend/maxmsp/mcs.nn_tilde/CMakeLists.txt index 45ed758..33844eb 100755 --- a/src/frontend/maxmsp/mcs.nn_tilde/CMakeLists.txt +++ b/src/frontend/maxmsp/mcs.nn_tilde/CMakeLists.txt @@ -7,6 +7,10 @@ set(C74_MIN_API_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../min-api) include(${C74_MIN_API_DIR}/script/min-pretarget.cmake) +if (APPLE) + set(CMAKE_OSX_DEPLOYMENT_TARGET "11.0") +endif() + ############################################################# # MAX EXTERNAL ############################################################# @@ -70,3 +74,6 @@ if (CMAKE_OSX_ARCHITECTURES STREQUAL "arm64") endif() endif() +if (MSVC) + set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 20) +endif() \ No newline at end of file diff --git a/src/frontend/maxmsp/mcs.nn_tilde/mcs.nn_tilde.cpp b/src/frontend/maxmsp/mcs.nn_tilde/mcs.nn_tilde.cpp index d9af9d9..a84664f 100644 --- a/src/frontend/maxmsp/mcs.nn_tilde/mcs.nn_tilde.cpp +++ b/src/frontend/maxmsp/mcs.nn_tilde/mcs.nn_tilde.cpp @@ -1,6 +1,8 @@ #include "../../../backend/backend.h" #include "../shared/circular_buffer.h" #include "c74_min.h" +#include +#include #include #include #include @@ -60,8 +62,10 @@ class mc_bnn_tilde : public object, public mc_operator<> { // void reset_buffers(); // AUDIO PERFORM - bool m_use_thread; + bool m_use_thread, m_should_stop_perform_thread; std::unique_ptr m_compute_thread; + std::binary_semaphore m_data_available_lock, m_result_available_lock; + void operator()(audio_bundle input, audio_bundle output); void perform(audio_bundle input, audio_bundle output); @@ -171,10 +175,31 @@ void model_perform(mc_bnn_tilde *mc_nn_instance) { mc_nn_instance->m_method, mc_nn_instance->get_batches()); } +void model_perform_loop(mc_bnn_tilde *mc_nn_instance) { + std::vector in_model, out_model; + + for (auto &ptr : mc_nn_instance->m_in_model) + in_model.push_back(ptr.get()); + + for (auto &ptr : mc_nn_instance->m_out_model) + out_model.push_back(ptr.get()); + + while (!mc_nn_instance->m_should_stop_perform_thread) { + if (mc_nn_instance->m_data_available_lock.try_acquire_for( + std::chrono::milliseconds(200))) { + mc_nn_instance->m_model->perform( + in_model, out_model, mc_nn_instance->m_buffer_size, + mc_nn_instance->m_method, mc_nn_instance->get_batches()); + mc_nn_instance->m_result_available_lock.release(); + } + } +} + mc_bnn_tilde::mc_bnn_tilde(const atoms &args) : m_compute_thread(nullptr), m_in_dim(1), m_in_ratio(1), m_out_dim(1), m_out_ratio(1), m_buffer_size(4096), m_batches(1), m_method("forward"), - m_use_thread(true) { + m_use_thread(true), m_data_available_lock(0), m_result_available_lock(1), + m_should_stop_perform_thread(false) { m_model = std::make_unique(); @@ -294,9 +319,13 @@ mc_bnn_tilde::mc_bnn_tilde(const atoms &args) m_out_buffer[i].initialize(m_buffer_size); m_out_model.push_back(std::make_unique(m_buffer_size)); } + + if (m_use_thread) + m_compute_thread = std::make_unique(model_perform_loop, this); } mc_bnn_tilde::~mc_bnn_tilde() { + m_should_stop_perform_thread = true; if (m_compute_thread) m_compute_thread->join(); } @@ -361,24 +390,30 @@ void mc_bnn_tilde::perform(audio_bundle input, audio_bundle output) { } if (m_in_buffer[0].full()) { // BUFFER IS FULL - // IF USE THREAD, CHECK THAT COMPUTATION IS OVER - if (m_compute_thread && m_use_thread) { - m_compute_thread->join(); - } - - // TRANSFER MEMORY BETWEEN INPUT CIRCULAR BUFFER AND MODEL BUFFER - for (int c(0); c < m_in_dim * get_batches(); c++) - m_in_buffer[c].get(m_in_model[c].get(), m_buffer_size); + if (!m_use_thread) { + // TRANSFER MEMORY BETWEEN INPUT CIRCULAR BUFFER AND MODEL BUFFER + for (int c(0); c < m_in_dim; c++) + m_in_buffer[c].get(m_in_model[c].get(), m_buffer_size); - if (!m_use_thread) // PROCESS DATA RIGHT NOW + // CALL MODEL PERFORM IN CURRENT THREAD model_perform(this); - // TRANSFER MEMORY BETWEEN OUTPUT CIRCULAR BUFFER AND MODEL BUFFER - for (int c(0); c < m_out_dim * get_batches(); c++) - m_out_buffer[c].put(m_out_model[c].get(), m_buffer_size); + // TRANSFER MEMORY BETWEEN OUTPUT CIRCULAR BUFFER AND MODEL BUFFER + for (int c(0); c < m_out_dim; c++) + m_out_buffer[c].put(m_out_model[c].get(), m_buffer_size); - if (m_use_thread) // PROCESS DATA LATER - m_compute_thread = std::make_unique(model_perform, this); + } else if (m_result_available_lock.try_acquire()) { + // TRANSFER MEMORY BETWEEN INPUT CIRCULAR BUFFER AND MODEL BUFFER + for (int c(0); c < m_in_dim; c++) + m_in_buffer[c].get(m_in_model[c].get(), m_buffer_size); + + // TRANSFER MEMORY BETWEEN OUTPUT CIRCULAR BUFFER AND MODEL BUFFER + for (int c(0); c < m_out_dim; c++) + m_out_buffer[c].put(m_out_model[c].get(), m_buffer_size); + + // SIGNAL PERFORM THREAD THAT DATA IS AVAILABLE + m_data_available_lock.release(); + } } // COPY CIRCULAR BUFFER TO OUTPUT @@ -388,12 +423,6 @@ void mc_bnn_tilde::perform(audio_bundle input, audio_bundle output) { m_out_buffer[b * m_out_dim + d].get(out, vec_size); } } - // for (int b(0); b < m_outlets.size(); b++) { - // for (int d(0); d < m_out_dim; d++) { - // auto out = output.samples(b * n_batches + d); - // m_out_buffer[d * n_batches + b].get(out, vec_size); - // } - // } } long simplemc_multichanneloutputs(c74::max::t_object *x, long index,