diff --git a/BUILD.bazel b/BUILD.bazel index 3b56d6777..0463f4cc2 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -1819,6 +1819,7 @@ cc_binary( "//:global_state_accessor_lib", "//:src/ray/ray_exported_symbols.lds", "//:src/ray/ray_version_script.lds", + "//:stats_lib", "@bazel_tools//tools/jdk:jni", ], ) diff --git a/java/generate_jni_header_files.sh b/java/generate_jni_header_files.sh index c5470ce4f..618bc4571 100755 --- a/java/generate_jni_header_files.sh +++ b/java/generate_jni_header_files.sh @@ -40,7 +40,8 @@ generate_one io.ray.runtime.actor.NativeActorHandle generate_one io.ray.runtime.object.NativeObjectStore generate_one io.ray.runtime.task.NativeTaskExecutor generate_one io.ray.runtime.gcs.GlobalStateAccessor +generate_one io.ray.runtime.metric.NativeMetric # Remove empty files rm -f io_ray_runtime_RayNativeRuntime_AsyncContext.h -rm -f io_ray_runtime_task_NativeTaskExecutor_NativeActorContext.h \ No newline at end of file +rm -f io_ray_runtime_task_NativeTaskExecutor_NativeActorContext.h diff --git a/java/runtime/src/main/java/io/ray/runtime/gcs/GlobalStateAccessor.java b/java/runtime/src/main/java/io/ray/runtime/gcs/GlobalStateAccessor.java index 57e344e03..c0116ec4c 100644 --- a/java/runtime/src/main/java/io/ray/runtime/gcs/GlobalStateAccessor.java +++ b/java/runtime/src/main/java/io/ray/runtime/gcs/GlobalStateAccessor.java @@ -135,8 +135,6 @@ public class GlobalStateAccessor { private native boolean nativeConnect(long nativePtr); - private native void nativeDisconnect(long nativePtr); - private native List nativeGetAllJobInfo(long nativePtr); private native List nativeGetAllNodeInfo(long nativePtr); diff --git a/java/runtime/src/main/java/io/ray/runtime/metric/Count.java b/java/runtime/src/main/java/io/ray/runtime/metric/Count.java new file mode 100644 index 000000000..b196621e0 --- /dev/null +++ b/java/runtime/src/main/java/io/ray/runtime/metric/Count.java @@ -0,0 +1,47 @@ +package io.ray.runtime.metric; + +import com.google.common.base.Preconditions; + +import java.util.Map; +import java.util.stream.Collectors; + +public class Count extends Metric { + + private double count; + + public Count(String name, String description, String unit, Map tags) { + super(name, tags); + count = 0.0d; + metricNativePointer = NativeMetric.registerCountNative(name, description, unit, + tags.keySet().stream().map(TagKey::getTagKey).collect(Collectors.toList())); + Preconditions.checkState(metricNativePointer != 0, "Count native pointer must not be 0."); + } + + @Override + public void update(double value) { + super.update(value); + count += value; + } + + @Override + public void update(double value, Map tags) { + super.update(value, tags); + count += value; + } + + @Override + public void reset() { + + } + + public double getCount() { + return count; + } + + /** + * @param delta add delta for counter + */ + public void inc(double delta) { + update(delta); + } +} diff --git a/java/runtime/src/main/java/io/ray/runtime/metric/Gauge.java b/java/runtime/src/main/java/io/ray/runtime/metric/Gauge.java new file mode 100644 index 000000000..2cafd6903 --- /dev/null +++ b/java/runtime/src/main/java/io/ray/runtime/metric/Gauge.java @@ -0,0 +1,25 @@ +package io.ray.runtime.metric; + +import com.google.common.base.Preconditions; +import java.util.Map; +import java.util.stream.Collectors; + + +/** + * Gauge metric for recording last value and mapping object from stats. + */ +public class Gauge extends Metric { + + public Gauge(String name, String description, String unit, Map tags) { + super(name, tags); + metricNativePointer = NativeMetric.registerGaugeNative(name, description, unit, + tags.keySet().stream().map(TagKey::getTagKey).collect(Collectors.toList())); + Preconditions.checkState(metricNativePointer != 0, "Gauge native pointer must not be 0."); + } + + @Override + public void reset() { + + } +} + diff --git a/java/runtime/src/main/java/io/ray/runtime/metric/Histogram.java b/java/runtime/src/main/java/io/ray/runtime/metric/Histogram.java new file mode 100644 index 000000000..abc3d2fb0 --- /dev/null +++ b/java/runtime/src/main/java/io/ray/runtime/metric/Histogram.java @@ -0,0 +1,58 @@ +package io.ray.runtime.metric; + +import com.google.common.base.Preconditions; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Histogram measurement is mapped to histogram object in stats. + * In order to reduce JNI calls overhead, a memory historical window is used + * for storing transient value and we assume its max size is 100. + */ +public class Histogram extends Metric { + + private List histogramWindow; + public static final int HISTOGRAM_WINDOW_SIZE = 100; + + public Histogram(String name, String description, String unit, List boundaries, + Map tags) { + super(name, tags); + metricNativePointer = NativeMetric.registerHistogramNative(name, description, unit, + boundaries.stream().mapToDouble(Double::doubleValue).toArray(), + tags.keySet().stream().map(TagKey::getTagKey).collect(Collectors.toList())); + Preconditions.checkState(metricNativePointer != 0, + "Histogram native pointer must not be 0."); + histogramWindow = new ArrayList<>(); + } + + private void updateForWindow(double value) { + if (histogramWindow.size() == HISTOGRAM_WINDOW_SIZE) { + histogramWindow.remove(0); + } + histogramWindow.add(value); + } + + @Override + public void update(double value) { + super.update(value); + updateForWindow(value); + } + + @Override + public void update(double value, Map tags) { + super.update(value, tags); + updateForWindow(value); + } + + @Override + public void reset() { + + } + + public List getHistogramWindow() { + return histogramWindow; + } +} diff --git a/java/runtime/src/main/java/io/ray/runtime/metric/Metric.java b/java/runtime/src/main/java/io/ray/runtime/metric/Metric.java new file mode 100644 index 000000000..da599d860 --- /dev/null +++ b/java/runtime/src/main/java/io/ray/runtime/metric/Metric.java @@ -0,0 +1,91 @@ +package io.ray.runtime.metric; + +import com.google.common.base.Preconditions; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Class metric is mapped to stats metric object in core worker. + * it must be in categories set [Gague, Count, Sum, Histogram]. + */ +public abstract class Metric { + protected String name; + + protected double value; + // Native pointer mapping to gauge object of stats. + protected long metricNativePointer = 0L; + + protected Map tags; + + public Metric(String name, Map tags) { + Preconditions.checkNotNull(tags, "Metric tags map must not be null."); + Preconditions.checkNotNull(name, "Metric name must not be null."); + this.name = name; + this.tags = tags; + this.value = 0.0d; + } + + // Sync metric with core worker stats for registry. + // Metric data will be flushed into stats view data inside core worker immediately after + // record is called. + /** + * Flush records to stats in last aggregator. + */ + public void record() { + Preconditions.checkState(metricNativePointer != 0, "Metric native pointer must not be 0."); + // Get tag key list from map; + List nativeTagKeyList = new ArrayList<>(); + List tagValues = new ArrayList<>(); + for (Map.Entry entry : tags.entrySet()) { + nativeTagKeyList.add(entry.getKey()); + tagValues.add(entry.getValue()); + } + // Get tag value list from map; + NativeMetric.recordNative(metricNativePointer, value, nativeTagKeyList.stream() + .map(TagKey::getTagKey).collect(Collectors.toList()), tagValues); + } + + /** Update gauge value without tags. + * Update metric info for user. + * @param value lastest value for updating + */ + public void update(double value) { + this.value = value; + + } + + /** Update gauge value with dynamic tag values. + * @param value lastest value for updating + * @param tags tag map + */ + public void update(double value, Map tags) { + this.value = value; + this.tags = tags; + } + + /** + * Deallocate object from stats and reset native pointer in null. + */ + public void unregister() { + if (0 != metricNativePointer) { + NativeMetric.unregisterMetricNative(metricNativePointer); + } + metricNativePointer = 0; + } + + /** + * @return lastest updating value. + */ + public double getValue() { + return value; + } + + /** + * It's abstract method for each metric measurements, so metric registry can store transient + * value and aggregate historical data for flushing. + */ + public abstract void reset(); +} diff --git a/java/runtime/src/main/java/io/ray/runtime/metric/NativeMetric.java b/java/runtime/src/main/java/io/ray/runtime/metric/NativeMetric.java new file mode 100644 index 000000000..0d85e91ee --- /dev/null +++ b/java/runtime/src/main/java/io/ray/runtime/metric/NativeMetric.java @@ -0,0 +1,31 @@ +package io.ray.runtime.metric; + +import java.util.List; + +/** + * Native metric provide a native interface to register tag or metric for current metric package. + */ +class NativeMetric { + public static native void registerTagkeyNative(String tagKey); + + public static native long registerCountNative(String name, String description, + String unit, List tagKeys); + + public static native long registerGaugeNative(String name, String description, + String unit, List tagKeys); + + public static native long registerHistogramNative(String name, String description, + String unit, double[] boundaries, + List tagKeys); + + public static native long registerSumNative(String name, String description, + String unit, List tagKeys); + + public static native void recordNative(long metricNativePointer, double value, + List tagKeys, List tagValues); + + public static native void unregisterMetricNative(long gaugePtr); + + + +} diff --git a/java/runtime/src/main/java/io/ray/runtime/metric/Sum.java b/java/runtime/src/main/java/io/ray/runtime/metric/Sum.java new file mode 100644 index 000000000..d55116388 --- /dev/null +++ b/java/runtime/src/main/java/io/ray/runtime/metric/Sum.java @@ -0,0 +1,44 @@ +package io.ray.runtime.metric; + + +import com.google.common.base.Preconditions; + +import java.util.Map; +import java.util.stream.Collectors; + +/** + * Sum measurement is mapped to sum object in stats. + * Property sum is used for storing transient sum for registry aggregation. + */ +public class Sum extends Metric { + private double sum; + + public Sum(String name, String description, String unit, Map tags) { + super(name, tags); + metricNativePointer = NativeMetric.registerSumNative(name, description, unit, + tags.keySet().stream().map(TagKey::getTagKey).collect(Collectors.toList())); + Preconditions.checkState(metricNativePointer != 0,"Count native pointer must not be 0."); + this.sum = 0.0d; + } + + @Override + public void update(double value) { + super.update(value); + sum += value; + } + + @Override + public void update(double value, Map tags) { + super.update(value, tags); + sum += value; + } + + @Override + public void reset() { + + } + + public double getSum() { + return sum; + } +} diff --git a/java/runtime/src/main/java/io/ray/runtime/metric/TagKey.java b/java/runtime/src/main/java/io/ray/runtime/metric/TagKey.java new file mode 100644 index 000000000..731417f9f --- /dev/null +++ b/java/runtime/src/main/java/io/ray/runtime/metric/TagKey.java @@ -0,0 +1,44 @@ +package io.ray.runtime.metric; + +import java.util.Objects; + +/** + * Tagkey is mapping java object to stats tagkey object. + */ +public class TagKey { + + private String tagKey; + + public TagKey(String key) { + tagKey = key; + NativeMetric.registerTagkeyNative(key); + } + + public String getTagKey() { + return tagKey; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof TagKey)) { + return false; + } + TagKey tagKey1 = (TagKey) o; + return Objects.equals(tagKey, tagKey1.tagKey); + } + + @Override + public int hashCode() { + return Objects.hash(tagKey); + } + + @Override + public String toString() { + return "TagKey{" + + ", tagKey='" + tagKey + '\'' + + '}'; + } +} \ No newline at end of file diff --git a/java/test/src/main/java/io/ray/test/MetricTest.java b/java/test/src/main/java/io/ray/test/MetricTest.java new file mode 100644 index 000000000..ec3a46ef6 --- /dev/null +++ b/java/test/src/main/java/io/ray/test/MetricTest.java @@ -0,0 +1,87 @@ +package io.ray.test; + +import io.ray.runtime.metric.Count; +import io.ray.runtime.metric.Gauge; +import io.ray.runtime.metric.Histogram; +import io.ray.runtime.metric.Sum; +import io.ray.runtime.metric.TagKey; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.testng.Assert; +import org.testng.annotations.Test; + +public class MetricTest extends BaseTest { + + boolean doubleEqual(double value, double other) { + return value <= other + 1e-5 && value >= other - 1e-5; + } + + @Test + public void testAddGauge() { + TestUtils.skipTestUnderSingleProcess(); + Map tags = new HashMap<>(); + tags.put(new TagKey("tag1"), "value1"); + + Gauge gauge = new Gauge("metric1", "", "", tags); + gauge.update(2); + gauge.record(); + Assert.assertTrue(doubleEqual(gauge.getValue(), 2.0)); + gauge.unregister(); + } + + @Test + public void testAddCount() { + TestUtils.skipTestUnderSingleProcess(); + Map tags = new HashMap<>(); + tags.put(new TagKey("tag1"), "value1"); + tags.put(new TagKey("count_tag"), "default"); + + Count count = new Count("metric_count", "counter", "1pc", tags); + count.inc(10.0); + count.inc(20.0); + count.record(); + Assert.assertTrue(doubleEqual(count.getValue(), 20.0)); + Assert.assertTrue(doubleEqual(count.getCount(), 30.0)); + } + + @Test + public void testAddSum() { + TestUtils.skipTestUnderSingleProcess(); + Map tags = new HashMap<>(); + tags.put(new TagKey("tag1"), "value1"); + tags.put(new TagKey("sum_tag"), "default"); + + Sum sum = new Sum("metric_sum", "sum", "sum", tags); + sum.update(10.0); + sum.update(20.0); + sum.record(); + Assert.assertTrue(doubleEqual(sum.getValue(), 20.0)); + Assert.assertTrue(doubleEqual(sum.getSum(), 30.0)); + } + + @Test + public void testAddHistogram() { + TestUtils.skipTestUnderSingleProcess(); + Map tags = new HashMap<>(); + tags.put(new TagKey("tag1"), "value1"); + tags.put(new TagKey("histogram_tag"), "default"); + List boundaries = new ArrayList<>(); + boundaries.add(10.0); + boundaries.add(15.0); + boundaries.add(12.0); + Histogram histogram = new Histogram("metric_histogram", "histogram", "1pc", + boundaries, tags); + for (int i = 1; i <= 200; ++i) { + histogram.update(i * 1.0d); + histogram.record(); + } + List window = histogram.getHistogramWindow(); + for (int i = 0; i < Histogram.HISTOGRAM_WINDOW_SIZE; ++i) { + Assert.assertTrue(doubleEqual(i + 101.0d, window.get(i))); + } + } +} diff --git a/src/ray/core_worker/lib/java/io_ray_runtime_metric_NativeMetric.cc b/src/ray/core_worker/lib/java/io_ray_runtime_metric_NativeMetric.cc new file mode 100644 index 000000000..038b494d5 --- /dev/null +++ b/src/ray/core_worker/lib/java/io_ray_runtime_metric_NativeMetric.cc @@ -0,0 +1,145 @@ +// Copyright 2017 The Ray Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "io_ray_runtime_metric_NativeMetric.h" +#include "jni_utils.h" +#include "ray/stats/metric.h" + +#include + +#include +#include "opencensus/tags/tag_key.h" + +using TagKeyType = opencensus::tags::TagKey; +using TagsType = std::vector>; + +/// Convert jni metric related data to native type for stats. +/// \param[in] j_name metric name in jni string. +/// \param[in] j_description metric description in jni string. +/// \param[in] j_unit metric measurement unit in jni string. +/// \param[in] tag_key_list tag key list in java list. +/// \param[out] metric_name metric name in native string. +/// \param[out] description metric description in native string. +/// \param[out] unit metric measurement unit in native string. +/// \param[out] tag_keys metric tag key vector unit in native vector. +inline void MetricTransform(JNIEnv *env, jstring j_name, jstring j_description, + jstring j_unit, jobject tag_key_list, + std::string *metric_name, std::string *description, + std::string *unit, std::vector &tag_keys) { + *metric_name = JavaStringToNativeString(env, static_cast(j_name)); + *description = JavaStringToNativeString(env, static_cast(j_description)); + *unit = JavaStringToNativeString(env, static_cast(j_unit)); + std::vector tag_key_str_list; + JavaStringListToNativeStringVector(env, tag_key_list, &tag_key_str_list); + // We just call TagKeyType::Register to get tag object since opencensus tags + // registry is thread-safe and registry can return a new tag or registered + // item when it already exists. + std::transform(tag_key_str_list.begin(), tag_key_str_list.end(), + std::back_inserter(tag_keys), + [](std::string tag_key) { return TagKeyType::Register(tag_key); }); +} + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT void JNICALL Java_io_ray_runtime_metric_NativeMetric_registerTagkeyNative( + JNIEnv *env, jclass obj, jstring str) { + std::string tag_key_name = JavaStringToNativeString(env, static_cast(str)); + RAY_IGNORE_EXPR(TagKeyType::Register(tag_key_name)); +} + +JNIEXPORT jlong JNICALL Java_io_ray_runtime_metric_NativeMetric_registerGaugeNative( + JNIEnv *env, jclass obj, jstring j_name, jstring j_description, jstring j_unit, + jobject tag_key_list) { + std::string metric_name; + std::string description; + std::string unit; + std::vector tag_keys; + MetricTransform(env, j_name, j_description, j_unit, tag_key_list, &metric_name, + &description, &unit, tag_keys); + auto *gauge = new ray::stats::Gauge(metric_name, description, unit, tag_keys); + return reinterpret_cast(gauge); +} + +JNIEXPORT jlong JNICALL Java_io_ray_runtime_metric_NativeMetric_registerCountNative( + JNIEnv *env, jclass obj, jstring j_name, jstring j_description, jstring j_unit, + jobject tag_key_list) { + std::string metric_name; + std::string description; + std::string unit; + std::vector tag_keys; + MetricTransform(env, j_name, j_description, j_unit, tag_key_list, &metric_name, + &description, &unit, tag_keys); + auto *count = new ray::stats::Count(metric_name, description, unit, tag_keys); + return reinterpret_cast(count); +} + +JNIEXPORT jlong JNICALL Java_io_ray_runtime_metric_NativeMetric_registerSumNative( + JNIEnv *env, jclass obj, jstring j_name, jstring j_description, jstring j_unit, + jobject tag_key_list) { + std::string metric_name; + std::string description; + std::string unit; + std::vector tag_keys; + MetricTransform(env, j_name, j_description, j_unit, tag_key_list, &metric_name, + &description, &unit, tag_keys); + auto *sum = new ray::stats::Sum(metric_name, description, unit, tag_keys); + return reinterpret_cast(sum); +} + +JNIEXPORT jlong JNICALL Java_io_ray_runtime_metric_NativeMetric_registerHistogramNative( + JNIEnv *env, jclass obj, jstring j_name, jstring j_description, jstring j_unit, + jdoubleArray j_boundaries, jobject tag_key_list) { + std::string metric_name; + std::string description; + std::string unit; + std::vector tag_keys; + MetricTransform(env, j_name, j_description, j_unit, tag_key_list, &metric_name, + &description, &unit, tag_keys); + std::vector boundaries; + + JavaDoubleArrayToNativeDoubleVector(env, j_boundaries, &boundaries); + + auto *histogram = + new ray::stats::Histogram(metric_name, description, unit, boundaries, tag_keys); + return reinterpret_cast(histogram); +} + +JNIEXPORT void JNICALL Java_io_ray_runtime_metric_NativeMetric_unregisterMetricNative( + JNIEnv *env, jclass obj, jlong metric_native_pointer) { + ray::stats::Metric *metric = + reinterpret_cast(metric_native_pointer); + delete metric; +} + +JNIEXPORT void JNICALL Java_io_ray_runtime_metric_NativeMetric_recordNative( + JNIEnv *env, jclass obj, jlong metric_native_pointer, jdouble value, + jobject tag_key_list, jobject tag_value_list) { + ray::stats::Metric *metric = + reinterpret_cast(metric_native_pointer); + std::vector tag_key_str_list; + std::vector tag_value_str_list; + JavaStringListToNativeStringVector(env, tag_key_list, &tag_key_str_list); + JavaStringListToNativeStringVector(env, tag_value_list, &tag_value_str_list); + TagsType tags; + for (size_t i = 0; i < tag_key_str_list.size(); ++i) { + tags.push_back({TagKeyType::Register(tag_key_str_list[i]), tag_value_str_list[i]}); + } + metric->Record(value, tags); +} + +#ifdef __cplusplus +} +#endif diff --git a/src/ray/core_worker/lib/java/io_ray_runtime_metric_NativeMetric.h b/src/ray/core_worker/lib/java/io_ray_runtime_metric_NativeMetric.h new file mode 100644 index 000000000..54159f6fa --- /dev/null +++ b/src/ray/core_worker/lib/java/io_ray_runtime_metric_NativeMetric.h @@ -0,0 +1,69 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class io_ray_runtime_metric_NativeMetric */ + +#ifndef _Included_io_ray_runtime_metric_NativeMetric +#define _Included_io_ray_runtime_metric_NativeMetric +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: io_ray_runtime_metric_NativeMetric + * Method: registerTagkeyNative + * Signature: (Ljava/lang/String;)V + */ +JNIEXPORT void JNICALL +Java_io_ray_runtime_metric_NativeMetric_registerTagkeyNative(JNIEnv *, jclass, jstring); + +/* + * Class: io_ray_runtime_metric_NativeMetric + * Method: registerCountNative + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)J + */ +JNIEXPORT jlong JNICALL Java_io_ray_runtime_metric_NativeMetric_registerCountNative( + JNIEnv *, jclass, jstring, jstring, jstring, jobject); + +/* + * Class: io_ray_runtime_metric_NativeMetric + * Method: registerGaugeNative + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)J + */ +JNIEXPORT jlong JNICALL Java_io_ray_runtime_metric_NativeMetric_registerGaugeNative( + JNIEnv *, jclass, jstring, jstring, jstring, jobject); + +/* + * Class: io_ray_runtime_metric_NativeMetric + * Method: registerHistogramNative + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[DLjava/util/List;)J + */ +JNIEXPORT jlong JNICALL Java_io_ray_runtime_metric_NativeMetric_registerHistogramNative( + JNIEnv *, jclass, jstring, jstring, jstring, jdoubleArray, jobject); + +/* + * Class: io_ray_runtime_metric_NativeMetric + * Method: registerSumNative + * Signature: (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/util/List;)J + */ +JNIEXPORT jlong JNICALL Java_io_ray_runtime_metric_NativeMetric_registerSumNative( + JNIEnv *, jclass, jstring, jstring, jstring, jobject); + +/* + * Class: io_ray_runtime_metric_NativeMetric + * Method: recordNative + * Signature: (JDLjava/util/List;Ljava/util/List;)V + */ +JNIEXPORT void JNICALL Java_io_ray_runtime_metric_NativeMetric_recordNative( + JNIEnv *, jclass, jlong, jdouble, jobject, jobject); + +/* + * Class: io_ray_runtime_metric_NativeMetric + * Method: unregisterMetricNative + * Signature: (J)V + */ +JNIEXPORT void JNICALL +Java_io_ray_runtime_metric_NativeMetric_unregisterMetricNative(JNIEnv *, jclass, jlong); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/src/ray/core_worker/lib/java/jni_utils.h b/src/ray/core_worker/lib/java/jni_utils.h index 9ed2ac608..b6bcaaa63 100644 --- a/src/ray/core_worker/lib/java/jni_utils.h +++ b/src/ray/core_worker/lib/java/jni_utils.h @@ -15,12 +15,12 @@ #pragma once #include +#include #include "ray/common/buffer.h" #include "ray/common/function_descriptor.h" #include "ray/common/id.h" #include "ray/common/ray_object.h" -#include "ray/common/status.h" #include "ray/core_worker/core_worker.h" /// Boolean class @@ -282,6 +282,26 @@ inline void JavaStringListToNativeStringVector(JNIEnv *env, jobject java_list, }); } +/// Convert a Java long array to C++ std::vector. +inline void JavaLongArrayToNativeLongVector(JNIEnv *env, jlongArray long_array, + std::vector *native_vector) { + jlong *long_array_ptr = env->GetLongArrayElements(long_array, nullptr); + jsize vec_size = env->GetArrayLength(long_array); + native_vector->insert(native_vector->begin(), long_array_ptr, + long_array_ptr + vec_size); + env->ReleaseLongArrayElements(long_array, long_array_ptr, 0); +} + +/// Convert a Java double array to C++ std::vector. +inline void JavaDoubleArrayToNativeDoubleVector(JNIEnv *env, jdoubleArray double_array, + std::vector *native_vector) { + jdouble *double_array_ptr = env->GetDoubleArrayElements(double_array, nullptr); + jsize vec_size = env->GetArrayLength(double_array); + native_vector->insert(native_vector->begin(), double_array_ptr, + double_array_ptr + vec_size); + env->ReleaseDoubleArrayElements(double_array, double_array_ptr, 0); +} + /// Convert a C++ std::vector to a Java List. template inline jobject NativeVectorToJavaList( @@ -438,6 +458,6 @@ inline std::string GetActorFullName(bool global, std::string name) { return ""; } return global ? name - : ::ray::CoreWorkerProcess::GetCoreWorker().GetCurrentJobId().Hex() + "-" + - name; -} \ No newline at end of file + : ::ray::CoreWorkerProcess::GetCoreWorker().GetCurrentJobId().Hex() + + "-" + name; +}