Skip to content

Commit

Permalink
Add example for parallel sort (#15)
Browse files Browse the repository at this point in the history
* Add example for parallel sort

It is now clearer how to use this library. The example(s) are built by default.

---------

Authored-by: Connor-GH <[email protected]>
  • Loading branch information
Connor-GH authored Nov 16, 2024
1 parent 4bb45f8 commit 3d53d6d
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 3 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ edition = "2021"
readme = "README.md"
repository = "https://github.com/STEllAR-GROUP/hpx-rs"
description = """
Bindings to hpx for interoperating with stellar-group hpx library for
Bindings to hpx for interoperating with stellar-group hpx library for
concurrency and parallelism.
"""
categories = ["api-bindings"]
Expand All @@ -17,4 +17,4 @@ publish = false
hpx-sys = { path = "hpx-sys", version = "0.1.0" }

[workspace]
members = []
members = [ "hpx-examples"]
8 changes: 8 additions & 0 deletions hpx-examples/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "hpx-examples"
version = "0.1.0"
edition = "2021"

[dependencies]
hpx-sys = { path = "../hpx-sys", version = "0.1.0" }
rand = "0.8.5"
18 changes: 18 additions & 0 deletions hpx-examples/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use core::array::from_fn;
use rand;
use std::{env, process};

fn hpx_main(_: Vec<String>) -> i32 {
let numbers: &[i32; 16384] = &from_fn(|_| rand::random::<i32>());
let list: &mut Vec<i32> = &mut Vec::<i32>::from(numbers);
println!("{:#?}", list);
// Sort the array in parallel.
hpx_sys::ffi::hpx_sort_comp(list, |a, b| a < b);
println!("{:#?}", list);
hpx_sys::ffi::finalize();
return 0;
}
fn main() {
let args = env::args().collect::<Vec<String>>();
process::exit(hpx_sys::init(hpx_main, args));
}
34 changes: 33 additions & 1 deletion hpx-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,41 @@ pub mod ffi {
// Wrapper for the above Bindings.
// reffer to tests to understand how to use them. [NOTE: Not all bindings have wrapper.]
// ================================================================================================
use std::ffi::CString;
use std::env::Args;
use std::ffi::{CStr, CString};
use std::os::raw::c_char;

static mut FUNC_HOLDER: Option<fn(Vec<String>) -> i32> = None;

// Convert arguments from *mut *mut c_char to Vec<String>
// and call the saved Rust version of the function.
fn c_init(argc: i32, argv: *mut *mut c_char) -> i32 {
let mut vec_args: Vec<String> = Vec::new();

for i in 0..argc {
// SAFETY: We get the argv from a conversion from Vec<String>.
// The conversion, which is safe, perserves the arguments.
// Therefore, no null pointers.

let c_str: &CStr = unsafe { CStr::from_ptr(*argv.offset(i as isize)) };
let string = c_str.to_string_lossy().into_owned();
vec_args.push(string.to_string());
}

unsafe { FUNC_HOLDER.unwrap()(vec_args) }
}

pub fn init(func: fn(Vec<String>) -> i32, func_args: Vec<String>) -> i32 {
unsafe { FUNC_HOLDER = Some(func) };
let str_args: Vec<&str> = func_args.iter().map(|s| s.as_str()).collect::<Vec<&str>>();
let (argc, mut rust_argv) = create_c_args(&str_args);
let argv = rust_argv.as_mut_ptr();

unsafe {
return self::ffi::init(c_init, argc, argv);
}
}

pub fn create_c_args(args: &[&str]) -> (i32, Vec<*mut c_char>) {
let c_args: Vec<CString> = args.iter().map(|s| CString::new(*s).unwrap()).collect();
let ptrs: Vec<*mut c_char> = c_args.iter().map(|s| s.as_ptr() as *mut c_char).collect();
Expand Down

0 comments on commit 3d53d6d

Please sign in to comment.