GraphLab: Distributed Graph-Parallel API  2.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
org_graphlab_Core.cpp
Go to the documentation of this file.
1 /**
2  * Copyright (c) 2009 Carnegie Mellon University.
3  * All rights reserved.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an "AS
13  * IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
14  * express or implied. See the License for the specific language
15  * governing permissions and limitations under the License.
16  *
17  * For more about this software visit:
18  *
19  * http://www.graphlab.ml.cmu.edu
20  *
21  */
22 
23 /**
24  * @file org_graphlab_Core.cpp
25  *
26  * Contains the JNI interface for org.graphlab.Core. In general, applications
27  * will keep their graphs in the Java layer and access the engine through the
28  * JNI. This wrapper provides a proxy graph for the engine to manipulate and
29  * forwards update calls to the Java layer. To learn how to use this interface,
30  * refer to the org.graphlab.Core class and to the examples.
31  *
32  * @author Jiunn Haur Lim <[email protected]>
33  */
34 
35 #include <wordexp.h>
36 #include "org_graphlab_Core.hpp"
37 #include "org_graphlab_Updater.hpp"
39 
40 using namespace graphlab;
41 
42 //---------------------------------------------------------------
43 // jni_core static members
44 //---------------------------------------------------------------
45 
46 template<typename G, typename U>
47 JavaVM* jni_core<G, U>::mjvm = NULL;
48 
49 template<typename G, typename U>
50 const size_t jni_core<G, U>::ENV_ID = 1;
51 
52 #ifdef __cplusplus
53 extern "C" {
54 #endif
55 
56 //---------------------------------------------------------------
57 // static helper functions
58 //---------------------------------------------------------------
59 
60  static jlong createCore (JNIEnv *env, jobject obj, int argc, char **argv){
61 
62  // configure log level
63  global_logger().set_log_level(LOG_DEBUG);
64  global_logger().set_log_to_console(false);
65 
66  // set jvm, if we don't have it already
67  if (NULL == proxy_updater::core::get_jvm()){
68  JavaVM* jvm = NULL;
69  env->GetJavaVM(&jvm);
71  }
72 
73  // store env for this thread
75 
76  // allocate and configure core
78  if (NULL != argv){
79  (*jni_core)().parse_options(argc, argv);
80  }
81 
82  // return address of jni_core
83  return (long) jni_core;
84 
85  }
86 
87 //---------------------------------------------------------------
88 // JNI functions
89 //---------------------------------------------------------------
90 
91  JNIEXPORT jlong JNICALL
92  Java_org_graphlab_Core_createCore__
93  (JNIEnv *env, jobject obj){
94  return createCore(env, obj, 0, NULL);
95  }
96 
97  JNIEXPORT jlong JNICALL
98  Java_org_graphlab_Core_createCore__Ljava_lang_String_2
99  (JNIEnv *env, jobject obj, jstring command_line_args){
100 
101  // convert jstring to c string
102  const char *cstr = NULL;
103  cstr = env->GetStringUTFChars(command_line_args, NULL);
104  if (NULL == cstr) {
105  return 0; /* OutOfMemoryError already thrown */
106  }
107 
108  // prepend with dummy name
109  char buffer[1024];
110  snprintf(buffer, 1024, "x %s", cstr);
111  env->ReleaseStringUTFChars(command_line_args, cstr);
112 
113  // split string
114  wordexp_t we_result;
115  if (0 != wordexp(buffer, &we_result, 0)) return 0;
116 
117  // create core
118  jlong ptr = createCore(env, obj, we_result.we_wordc, we_result.we_wordv);
119 
120  // cleanup
121  wordfree(&we_result);
122  return ptr;
123 
124  }
125 
126  JNIEXPORT void JNICALL
127  Java_org_graphlab_Core_destroyCore
128  (JNIEnv *env, jobject obj, jlong ptr){
129 
130  if (NULL == env || 0 == ptr){
132  env,
133  "java/lang/IllegalArgumentException",
134  "ptr must not be null.");
135  return;
136  }
137 
138  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
139 
140  // cleanup core
141  delete jni_core;
142 
143  }
144 
145  JNIEXPORT void JNICALL
146  Java_org_graphlab_Core_resizeGraph
147  (JNIEnv *env, jobject obj, jlong ptr, jint count){
148 
149  if (NULL == env || 0 == ptr){
151  env,
152  "java/lang/IllegalArgumentException",
153  "ptr must not be null.");
154  return;
155  }
156 
157  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
158  (*jni_core)().graph().resize(count);
159 
160  }
161 
162  JNIEXPORT void JNICALL
163  Java_org_graphlab_Core_addVertex
164  (JNIEnv *env, jobject obj, jlong ptr,
165  jobject app_vertex, jint vertex_id){
166 
167  if (NULL == env || 0 == ptr){
169  env,
170  "java/lang/IllegalArgumentException",
171  "ptr must not be null.");
172  return;
173  }
174 
175  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
176 
177  // add to graph
178  (*jni_core)().graph()
179  .add_vertex(vertex_id, proxy_vertex(env, app_vertex));
180 
181  }
182 
183  JNIEXPORT void JNICALL
184  Java_org_graphlab_Core_addEdge
185  (JNIEnv *env, jobject obj, jlong ptr,
186  jint source, jint target, jobject app_edge){
187 
188  if (NULL == env || 0 == ptr){
190  env,
191  "java/lang/IllegalArgumentException",
192  "ptr must not be null.");
193  return;
194  }
195 
196  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
197 
198  // add to graph
199  (*jni_core)().graph().add_edge(source, target, proxy_edge(env, app_edge));
200 
201  }
202 
203  JNIEXPORT jdouble JNICALL
204  Java_org_graphlab_Core_start
205  (JNIEnv *env, jobject obj, jlong ptr){
206 
207  if (NULL == env || 0 == ptr){
209  env,
210  "java/lang/IllegalArgumentException",
211  "ptr must not be null.");
212  return 0;
213  }
214 
215  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
216  (*jni_core)().engine().get_options().print();
217 
218  double runtime = (*jni_core)().start();
219  return runtime;
220 
221  }
222 
223  JNIEXPORT jlong JNICALL
224  Java_org_graphlab_Core_lastUpdateCount
225  (JNIEnv *env, jobject obj, jlong ptr){
226 
227  if (NULL == env || 0 == ptr){
229  env,
230  "java/lang/IllegalArgumentException",
231  "ptr must not be null.");
232  return 0;
233  }
234 
235  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
236  return (*jni_core)().engine().last_update_count();
237 
238  }
239 
240  JNIEXPORT void JNICALL
241  Java_org_graphlab_Core_addGlobalConst
242  (JNIEnv *env, jobject obj, jlong ptr, jstring key, jobject to_store){
243 
244  if (NULL == env || 0 == ptr){
246  env,
247  "java/lang/IllegalArgumentException",
248  "ptr must not be null.");
249  return;
250  }
251 
252  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
253 
254  // convert jstring to c string
255  const char * key_str = env->GetStringUTFChars(key, NULL);
256 
257  (*jni_core)().add_global_const(std::string(key_str), java_any(env, to_store));
258 
259  // free memory
260  env->ReleaseStringUTFChars(key, key_str);
261 
262  return;
263 
264  }
265 
266  JNIEXPORT void JNICALL
267  Java_org_graphlab_Core_addGlobal
268  (JNIEnv *env, jobject obj, jlong ptr, jstring key, jobject to_store){
269 
270  if (NULL == env || 0 == ptr){
272  env,
273  "java/lang/IllegalArgumentException",
274  "ptr must not be null.");
275  return;
276  }
277 
278  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
279 
280  // convert jstring to c string
281  const char * key_str = env->GetStringUTFChars(key, NULL);
282 
283  java_any a = java_any(env, to_store);
284  (*jni_core)().add_global(std::string(key_str), a);
285 
286  // free memory
287  env->ReleaseStringUTFChars(key, key_str);
288 
289  return;
290 
291  }
292 
293  JNIEXPORT void JNICALL
294  Java_org_graphlab_Core_setGlobal
295  (JNIEnv *env, jobject obj, jlong ptr, jstring key, jobject to_store){
296 
297  if (NULL == env || 0 == ptr){
299  env,
300  "java/lang/IllegalArgumentException",
301  "ptr must not be null.");
302  return;
303  }
304 
305  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
306 
307  // convert jstring to c string
308  const char * key_str = env->GetStringUTFChars(key, NULL);
309 
310  java_any a = java_any(env, to_store);
311  (*jni_core)().set_global(std::string(key_str), a);
312 
313  // free memory
314  env->ReleaseStringUTFChars(key, key_str);
315 
316  return;
317 
318  }
319 
320 
321  JNIEXPORT jobject JNICALL
322  Java_org_graphlab_Core_getGlobal
323  (JNIEnv *env, jobject obj, jlong ptr, jstring key){
324 
325  if (NULL == env || 0 == ptr){
327  env,
328  "java/lang/IllegalArgumentException",
329  "ptr must not be null.");
330  return NULL;
331  }
332 
333  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
334 
335  // convert jstring to c string
336  const char * key_str = env->GetStringUTFChars(key, NULL);
337 
338  java_any stored = (*jni_core)().get_global<java_any>(std::string(key_str));
339 
340  // free memory
341  env->ReleaseStringUTFChars(key, key_str);
342 
343  return env->NewLocalRef(stored.obj());
344 
345  }
346 
347  JNIEXPORT void JNICALL
348  Java_org_graphlab_Core_setNCpus
349  (JNIEnv * env, jobject obj, jlong ptr, jlong ncpus) {
350 
351  if (NULL == env || 0 == ptr){
353  env,
354  "java/lang/IllegalArgumentException",
355  "ptr must not be null.");
356  return;
357  }
358 
359  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
360  (*jni_core)().set_ncpus(ncpus);
361 
362  }
363 
364  JNIEXPORT void JNICALL
365  Java_org_graphlab_Core_setSchedulerType
366  (JNIEnv * env, jobject obj, jlong ptr, jstring scheduler_str) {
367 
368  if (NULL == env || 0 == ptr){
370  env,
371  "java/lang/IllegalArgumentException",
372  "ptr must not be null.");
373  return;
374  }
375 
376  const char *str = env->GetStringUTFChars(scheduler_str, NULL);
377  if (NULL == str) return; // OutOfMemoryError already thrown
378 
379  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
380  (*jni_core)().set_scheduler_type(std::string(str));
381  env->ReleaseStringUTFChars(scheduler_str, str);
382 
383  }
384 
385  JNIEXPORT void JNICALL
386  Java_org_graphlab_Core_setScopeType
387  (JNIEnv * env, jobject obj, jlong ptr, jstring scope_str) {
388 
389  if (NULL == env || 0 == ptr){
391  env,
392  "java/lang/IllegalArgumentException",
393  "ptr must not be null.");
394  return;
395  }
396 
397  const char *str = env->GetStringUTFChars(scope_str, NULL);
398  if (NULL == str) return; // OutOfMemoryError already thrown
399 
400  proxy_updater::core *jni_core = (proxy_updater::core *) ptr;
401  (*jni_core)().set_scope_type(std::string(str));
402  env->ReleaseStringUTFChars(scope_str, str);
403 
404  }
405 
406  JNIEXPORT void JNICALL
407  Java_org_graphlab_Core_schedule
408  (JNIEnv * env, jobject obj,
409  jlong core_ptr, jobject updater, jint vertex_id){
410 
411  if (NULL == env || 0 == core_ptr){
413  env,
414  "java/lang/IllegalArgumentException",
415  "core_ptr must not be null.");
416  return;
417  }
418 
419  // get objects from pointers
420  proxy_updater::core *jni_core = (proxy_updater::core *) core_ptr;
421 
422  // schedule vertex
423  (*jni_core)().schedule(vertex_id, proxy_updater(env, updater));
424 
425  }
426 
427  JNIEXPORT void JNICALL
428  Java_org_graphlab_Core_scheduleAll
429  (JNIEnv * env, jobject obj,
430  jlong core_ptr, jobject updater) {
431 
432  if (NULL == env || 0 == core_ptr){
434  env,
435  "java/lang/IllegalArgumentException",
436  "core_ptr and updater_ptr must not be null.");
437  return;
438  }
439 
440  // get objects from pointers
441  proxy_updater::core *jni_core = (proxy_updater::core *) core_ptr;
442 
443  // schedule vertex
444  (*jni_core)().schedule_all(proxy_updater(env, updater));
445 
446  }
447 
448  JNIEXPORT void JNICALL
449  Java_org_graphlab_Core_addAggregator
450  (JNIEnv * env, jobject obj,
451  jlong core_ptr, jstring key, jobject aggregator,
452  jlong frequency){
453 
454  if (NULL == env || 0 == core_ptr){
456  env,
457  "java/lang/IllegalArgumentException",
458  "core_ptr and updater_ptr must not be null.");
459  return;
460  }
461 
462  // get objects from pointers
463  proxy_updater::core *jni_core = (proxy_updater::core *) core_ptr;
464 
465  // add aggregator
466  const char * key_str = env->GetStringUTFChars(key, NULL);
467  (*jni_core)().add_aggregator(std::string(key_str),
468  proxy_aggregator(env, aggregator),
469  frequency);
470  env->ReleaseStringUTFChars(key, key_str);
471 
472  }
473 
474  JNIEXPORT void JNICALL
475  Java_org_graphlab_Core_aggregateNow
476  (JNIEnv * env, jobject obj,
477  jlong core_ptr, jstring key){
478 
479  if (NULL == env || 0 == core_ptr){
481  env,
482  "java/lang/IllegalArgumentException",
483  "core_ptr and updater_ptr must not be null.");
484  return;
485  }
486 
487  // get objects from pointers
488  proxy_updater::core *jni_core = (proxy_updater::core *) core_ptr;
489 
490  // add aggregator
491  const char * key_str = env->GetStringUTFChars(key, NULL);
492  (*jni_core)().aggregate_now(std::string(key_str));
493  env->ReleaseStringUTFChars(key, key_str);
494 
495  }
496 
497 #ifdef __cplusplus
498 }
499 #endif