Skip to content

Commit

Permalink
Merge branch 'branch-24.06' of github.com:nv-morpheus/Morpheus into m…
Browse files Browse the repository at this point in the history
…ilvus-perf
  • Loading branch information
cwharris committed May 9, 2024
2 parents b3eb012 + 266612e commit fe89bee
Show file tree
Hide file tree
Showing 83 changed files with 720 additions and 609 deletions.
20 changes: 14 additions & 6 deletions ci/conda/recipes/run_conda_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ NUMARGS=$#
ARGS=$*

function hasArg {
(( ${NUMARGS} != 0 )) && (echo " ${ARGS} " | grep -q " $1 ")
(( ${NUMARGS} != 0 )) && (echo " ${ARGS} " | grep -q " $1 ")
}

function get_version() {
Expand Down Expand Up @@ -99,6 +99,14 @@ CONDA_ARGS_ARRAY+=("-c" "${CONDA_CHANNEL_ALIAS:+"${CONDA_CHANNEL_ALIAS%/}/"}nvid
CONDA_ARGS_ARRAY+=("-c" "${CONDA_CHANNEL_ALIAS:+"${CONDA_CHANNEL_ALIAS%/}/"}pytorch")
CONDA_ARGS_ARRAY+=("-c" "${CONDA_CHANNEL_ALIAS:+"${CONDA_CHANNEL_ALIAS%/}/"}defaults")

if [[ ${NUMARGS} == 0 ]]; then
echo -e "${r}ERROR: No arguments were provided. Please provide at least one package to build. Available packages:${x}"
echo -e "${r} morpheus${x}"
echo -e "${r} pydebug${x}"
echo -e "${r}Exiting...${x}"
exit 12
fi

if hasArg morpheus; then
# Set GIT_VERSION to set the project version inside of meta.yaml
export GIT_VERSION="$(get_version)"
Expand All @@ -110,10 +118,10 @@ if hasArg morpheus; then
fi

if hasArg pydebug; then
export MORPHEUS_PYTHON_VER=$(python --version | cut -d ' ' -f 2)
export MORPHEUS_PYTHON_VER=$(python --version | cut -d ' ' -f 2)

echo "Running conda-build for python-dbg..."
set -x
conda ${CONDA_COMMAND} "${CONDA_ARGS_ARRAY[@]}" ${CONDA_ARGS} ./ci/conda/recipes/python-dbg
set +x
echo "Running conda-build for python-dbg..."
set -x
conda ${CONDA_COMMAND} "${CONDA_ARGS_ARRAY[@]}" ${CONDA_ARGS} ./ci/conda/recipes/python-dbg
set +x
fi
4 changes: 3 additions & 1 deletion docker/build_conda_packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,9 @@ DOCKER_EXTRA_ARGS=()
BUILD_SCRIPT="${BUILD_SCRIPT}
export CONDA_ARGS=\"${CONDA_ARGS[@]}\"
./ci/conda/recipes/run_conda_build.sh "$@"
EXIT_CODE=\$?
chown -R ${CUR_UID}:${CUR_GID} .cache .conda-bld
exit \$EXIT_CODE
"

echo "Running conda build"
Expand All @@ -62,4 +64,4 @@ echo "Running conda build"
DOCKER_EXTRA_ARGS="${DOCKER_EXTRA_ARGS[@]}" ${SCRIPT_DIR}/run_container_dev.sh bash -c "${BUILD_SCRIPT}"

echo "Conda packages have been built. Use the following to install into an environment:"
echo " mamba install -c file://$(realpath ${MORPHEUS_ROOT}/.conda-bld) -c nvidia -c rapidsai -c conda-forge $@"
echo " mamba install -c file://$(realpath ${MORPHEUS_ROOT}/.conda-bld) -c conda-forge -c rapidsai -c rapidsai-nightly -c nvidia -c nvidia/label/dev $@"
5 changes: 4 additions & 1 deletion docker/run_container_dev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@ docker run \
-ti \
${DOCKER_ARGS} ${DOCKER_EXTRA_ARGS} \
${DOCKER_IMAGE_NAME}:${DOCKER_IMAGE_TAG} "${@:-bash}"
set +x

{ EXIT_CODE=$?; set +x; } 2>/dev/null

exit $EXIT_CODE
29 changes: 16 additions & 13 deletions docs/source/developer_guide/guides/3_simple_cpp_stage.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def supports_cpp_node(self):
return True
```

C++ message object declarations can be found in the header files that are located in the `morpheus/_lib/include/morpheus/messages` directory. For example, the `MessageMeta` class declaration is located in `morpheus/_lib/include/morpheus/messages/meta.hpp`. In code this would be included as:
C++ message object declarations can be found in the header files that are located in the `morpheus/_lib/include/morpheus/messages` directory. For example, the `MessageMeta` class declaration is located in `morpheus/_lib/include/morpheus/messages/meta.hpp`. Since this code is outside of the morpheus directory it would be included as:

```cpp
#include <morpheus/messages/meta.hpp>
Expand Down Expand Up @@ -89,6 +89,7 @@ While our Python implementation accepts messages of any type (in the form of Pyt
To start with, we have our Morpheus and MRC-specific includes:

```cpp
#include <morpheus/export.h>
#include <morpheus/messages/multi.hpp> // for MultiMessage
#include <mrc/segment/builder.hpp> // for Segment Builder
#include <mrc/segment/object.hpp> // for Segment Object
Expand All @@ -100,12 +101,10 @@ We'll want to define our stage in its own namespace. In this case, we will name
```cpp
namespace morpheus_example {

// pybind11 sets visibility to hidden by default; we want to export our symbols
#pragma GCC visibility push(default)

using namespace morpheus;

class PassThruStage : public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>
// pybind11 sets visibility to hidden by default; we want to export our symbols
class MORPHEUS_EXPORT PassThruStage : public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>
{
public:
using base_t = mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>;
Expand All @@ -119,7 +118,13 @@ class PassThruStage : public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage
};
```

We explicitly set the visibility for the stage object in the namespace to default. This is due to a pybind11 requirement for module implementations to default symbol visibility to hidden (`-fvisibility=hidden`). More details about this can be found in the [pybind11 documentation](https://pybind11.readthedocs.io/en/stable/faq.html#someclass-declared-with-greater-visibility-than-the-type-of-its-field-someclass-member-wattributes).
We explicitly set the visibility for the stage object to default by importing:
```cpp
#include <morpheus/export.h>
```
Then adding `MORPHEUS_EXPORT`, which is defined in `/build/autogenerated/include/morpheus/export.h` and is compiler agnostic, to the definition of the stage object.
This is due to a pybind11 requirement for module implementations to default symbol visibility to hidden (`-fvisibility=hidden`). More details about this can be found in the [pybind11 documentation](https://pybind11.readthedocs.io/en/stable/faq.html#someclass-declared-with-greater-visibility-than-the-type-of-its-field-someclass-member-wattributes).
Any object, struct, or function that is intended to be exported should have `MORPHEUS_EXPORT` included in the definition.

For simplicity, we defined `base_t` as an alias for our base class type because the definition can be quite long. Our base class type also defines a few additional type aliases for us: `subscribe_fn_t`, `sink_type_t` and `source_type_t`. The `sink_type_t` and `source_type_t` aliases are shortcuts for the sink and source types that this stage will be reading and writing. In this case both the `sink_type_t` and `source_type_t` resolve to `std::shared_ptr<MultiMessage>`. `subscribe_fn_t` (read as "subscribe function type") is an alias for:

Expand All @@ -134,7 +139,7 @@ All Morpheus C++ stages receive an instance of an MRC Segment Builder and a name
We will also define an interface proxy object to keep the class definition separated from the Python interface. This isn't strictly required, but it is a convention used internally by Morpheus. Our proxy object will define a static method named `init` which is responsible for constructing a `PassThruStage` instance and returning it wrapped in a `shared_ptr`. There are many common Python types that pybind11 [automatically converts](https://pybind11.readthedocs.io/en/latest/advanced/cast/overview.html#conversion-table) to their associated C++ types. The MRC `Builder` is a C++ object with Python bindings. However there are other instances such as checking for values of `None` where the casting from Python to C++ types is not automatic. The proxy interface object fulfills this need and is used to help insulate Python bindings from internal implementation details.

```cpp
struct PassThruStageInterfaceProxy
struct MORPHEUS_EXPORT PassThruStageInterfaceProxy
{
static std::shared_ptr<mrc::segment::Object<PassThruStage>> init(mrc::segment::Builder &builder,
const std::string &name);
Expand All @@ -146,6 +151,7 @@ struct PassThruStageInterfaceProxy
```cpp
#pragma once

#include <morpheus/export.h> // for exporting symbols
#include <morpheus/messages/multi.hpp> // for MultiMessage
#include <mrc/segment/builder.hpp> // for Segment Builder
#include <mrc/segment/object.hpp> // for Segment Object
Expand All @@ -156,12 +162,10 @@ struct PassThruStageInterfaceProxy

namespace morpheus_example {

// pybind11 sets visibility to hidden by default; we want to export our symbols
#pragma GCC visibility push(default)

using namespace morpheus;

class PassThruStage : public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>
// pybind11 sets visibility to hidden by default; we want to export our symbols
class MORPHEUS_EXPORT PassThruStage : public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>
{
public:
using base_t = mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>;
Expand All @@ -174,13 +178,12 @@ class PassThruStage : public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage
subscribe_fn_t build_operator();
};

struct PassThruStageInterfaceProxy
struct MORPHEUS_EXPORT PassThruStageInterfaceProxy
{
static std::shared_ptr<mrc::segment::Object<PassThruStage>> init(mrc::segment::Builder& builder,
const std::string& name);
};

#pragma GCC visibility pop
} // namespace morpheus_example
```

Expand Down
18 changes: 8 additions & 10 deletions docs/source/developer_guide/guides/4_source_cpp_stage.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ Our includes:
```cpp
#include <SimpleAmqpClient/SimpleAmqpClient.h> // for AmqpClient::Channel::ptr_t
#include <cudf/io/types.hpp> // for cudf::io::table_with_metadata
#include <morpheus/export.h> // for exporting symbols
#include <morpheus/messages/meta.hpp> // for MessageMeta
#include <mrc/segment/builder.hpp> // for Segment Builder
#include <mrc/segment/object.hpp> // for Segment Object
Expand All @@ -60,13 +61,11 @@ Our namespace and class definition is:
```cpp
namespace morpheus_rabbit {

// pybind11 sets visibility to hidden by default; we want to export our symbols
#pragma GCC visibility push(default)

using namespace std::literals;
using namespace morpheus;

class RabbitMQSourceStage : public mrc::pymrc::PythonSource<std::shared_ptr<MessageMeta>>
//pybind11 sets visibility to hidden by default; we want to export our symbols
class MORPHEUS_EXPORT RabbitMQSourceStage : public mrc::pymrc::PythonSource<std::shared_ptr<MessageMeta>>
{
public:
using base_t = mrc::pymrc::PythonSource<std::shared_ptr<MessageMeta>>;
Expand Down Expand Up @@ -115,6 +114,7 @@ Wrapping it all together, our header file should be similar to:

#include <SimpleAmqpClient/SimpleAmqpClient.h> // for AmqpClient::Channel::ptr_t
#include <cudf/io/types.hpp> // for cudf::io::table_with_metadata
#include <morpheus/export.h> // for exporting symbols
#include <morpheus/messages/meta.hpp> // for MessageMeta
#include <mrc/segment/builder.hpp> // for Segment Builder
#include <mrc/segment/object.hpp> // for Segment Object
Expand All @@ -126,13 +126,11 @@ Wrapping it all together, our header file should be similar to:

namespace morpheus_rabbit {

// pybind11 sets visibility to hidden by default; we want to export our symbols
#pragma GCC visibility push(default)

using namespace std::literals;
using namespace morpheus;

class RabbitMQSourceStage : public mrc::pymrc::PythonSource<std::shared_ptr<MessageMeta>>
// pybind11 sets visibility to hidden by default; we want to export our symbols
class MORPHEUS_EXPORT RabbitMQSourceStage : public mrc::pymrc::PythonSource<std::shared_ptr<MessageMeta>>
{
public:
using base_t = mrc::pymrc::PythonSource<std::shared_ptr<MessageMeta>>;
Expand Down Expand Up @@ -162,7 +160,7 @@ class RabbitMQSourceStage : public mrc::pymrc::PythonSource<std::shared_ptr<Mess
/**
* @brief Interface proxy, used to insulate Python bindings.
*/
struct RabbitMQSourceStageInterfaceProxy
struct MORPHEUS_EXPORT RabbitMQSourceStageInterfaceProxy
{
/**
* @brief Create and initialize a RabbitMQSourceStage, and return the result.
Expand All @@ -175,7 +173,7 @@ struct RabbitMQSourceStageInterfaceProxy
const std::string& queue_name,
std::chrono::milliseconds poll_interval);
};
#pragma GCC visibility pop

} // namespace morpheus_rabbit
```
Expand Down
7 changes: 4 additions & 3 deletions docs/source/developer_guide/guides/8_cpp_modules.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ The following example will create a simple C++ module that passes through the in

```c++
#pragma once
#include <morpheus/export.h>
#include <mrc/modules/properties/persistent.hpp>
#include <mrc/modules/segment_modules.hpp>
#include <nlohmann/json.hpp>

namespace morpheus {
#pragma GCC visibility push(default)
class MyTestModule: public mrc::modules::SegmentModule, public mrc::modules::PersistentModule

class MORPHEUS_EXPORT MyTestModule: public mrc::modules::SegmentModule, public mrc::modules::PersistentModule
{
using type_t = MyTestModule;

Expand All @@ -52,7 +53,7 @@ class MyTestModule: public mrc::modules::SegmentModule, public mrc::modules::Per
private:
int my_persistent_value{0};
};
#pragma GCC visibility pop

} // namespace morpheus
```

Expand Down
4 changes: 2 additions & 2 deletions examples/abp_pcap_detection/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,13 @@ Alternately, the Morpheus command line could have been used to accomplish the sa
From the root of the Morpheus repo, run:
```bash
morpheus --log_level INFO --plugin "examples/abp_pcap_detection/abp_pcap_preprocessing.py" \
run --use_cpp False --pipeline_batch_size 100000 --model_max_batch_size 100000 \
run --pipeline_batch_size 100000 --model_max_batch_size 100000 \
pipeline-fil --model_fea_length 13 --label=probs \
from-file --filename examples/data/abp_pcap_dump.jsonlines --filter_null False \
deserialize \
pcap-preprocess \
monitor --description "Preprocessing rate" \
inf-triton --model_name "abp-pcap-xgb" --server_url "localhost:8001" --force_convert_inputs=True \
inf-triton --model_name "abp-pcap-xgb" --server_url "localhost:8000" \
monitor --description "Inference rate" --unit inf \
add-class --label=probs \
monitor --description "Add classification rate" --unit "add-class" \
Expand Down
3 changes: 2 additions & 1 deletion examples/abp_pcap_detection/abp_pcap_preprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,8 @@ def round_time_kernel(timestamp, rollup_time, secs):
del df, grouped_df

# Convert the dataframe to cupy the same way cuml does
data = cp.asarray(merged_df[fea_cols].to_cupy())
# Explicity casting to float32 to match the model's input, and setting row-major as required by Triton
data = cp.asarray(merged_df[fea_cols].to_cupy(), order='C', dtype=cp.float32)
count = data.shape[0]

for col in req_cols:
Expand Down
17 changes: 3 additions & 14 deletions examples/abp_pcap_detection/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
from morpheus.cli.commands import FILE_TYPE_NAMES
from morpheus.cli.utils import str_to_file_type
from morpheus.config import Config
from morpheus.config import CppConfig
from morpheus.config import PipelineModes
from morpheus.pipeline.linear_pipeline import LinearPipeline
from morpheus.stages.general.monitor_stage import MonitorStage
Expand Down Expand Up @@ -87,7 +86,7 @@
help=("Iterative mode will emit dataframes one at a time. Otherwise a list of dataframes is emitted. "
"Iterative mode is good for interleaving source stages."),
)
@click.option("--server_url", required=True, help="Tritonserver url.", default="localhost:8001")
@click.option("--server_url", required=True, help="Tritonserver url.", default="localhost:8000")
@click.option(
"--file_type",
type=click.Choice(FILE_TYPE_NAMES, case_sensitive=False),
Expand All @@ -111,8 +110,6 @@ def run_pipeline(
# Enable the default logger.
configure_logging(log_level=logging.INFO)

CppConfig.set_should_use_cpp(False)

# Its necessary to get the global config object and configure it for FIL mode.
config = Config()
config.mode = PipelineModes.FIL
Expand All @@ -124,8 +121,6 @@ def run_pipeline(
config.feature_length = model_fea_length
config.class_labels = ["probs"]

kwargs = {}

# Create a linear pipeline object.
pipeline = LinearPipeline(config)

Expand Down Expand Up @@ -154,13 +149,7 @@ def run_pipeline(

# Add a inference stage.
# This stage sends inference requests to the Tritonserver and captures the response.
pipeline.add_stage(
TritonInferenceStage(
config,
model_name=model_name,
server_url=server_url,
force_convert_inputs=True,
))
pipeline.add_stage(TritonInferenceStage(config, model_name=model_name, server_url=server_url))

# Add a monitor stage.
# This stage logs the metrics (inf/sec) from the above stage.
Expand All @@ -176,7 +165,7 @@ def run_pipeline(

# Add a serialize stage.
# This stage includes & excludes columns from messages.
pipeline.add_stage(SerializeStage(config, **kwargs))
pipeline.add_stage(SerializeStage(config))

# Add a monitor stage.
# This stage logs the metrics (msg/sec) from the above stage.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#pragma once

#include <morpheus/export.h> // for exporting symbols
#include <morpheus/messages/multi.hpp> // for MultiMessage
#include <mrc/segment/builder.hpp> // for Segment Builder
#include <mrc/segment/object.hpp> // for Segment Object
Expand All @@ -32,12 +33,11 @@

namespace morpheus_example {

// pybind11 sets visibility to hidden by default; we want to export our symbols
#pragma GCC visibility push(default)

using namespace morpheus;

class PassThruStage : public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>
// pybind11 sets visibility to hidden by default; we want to export our symbols
class MORPHEUS_EXPORT PassThruStage
: public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>
{
public:
using base_t = mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage>, std::shared_ptr<MultiMessage>>;
Expand All @@ -50,11 +50,10 @@ class PassThruStage : public mrc::pymrc::PythonNode<std::shared_ptr<MultiMessage
subscribe_fn_t build_operator();
};

struct PassThruStageInterfaceProxy
struct MORPHEUS_EXPORT PassThruStageInterfaceProxy
{
static std::shared_ptr<mrc::segment::Object<PassThruStage>> init(mrc::segment::Builder& builder,
const std::string& name);
};

#pragma GCC visibility pop
} // namespace morpheus_example
Loading

0 comments on commit fe89bee

Please sign in to comment.