Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Getting Started

Get up and running with ROUP in 5 minutes. This guide covers installation, basic usage, and your first OpenMP parse for Rust, C, and C++.


Installation

Prerequisites

  • Rust 1.70+ (Install Rust)
  • C/C++ Compiler: Clang 10+ or GCC 9+ (for C/C++ usage)

Build ROUP

git clone https://github.com/ouankou/roup.git
cd roup
cargo build --release

This creates the library at:

  • Linux: target/release/libroup.so
  • macOS: target/release/libroup.dylib
  • Windows: target/release/roup.dll

Quick Start: Rust

1. Add Dependency

Add to your Cargo.toml:

[dependencies]
roup = "0.3"

Or use the git version:

[dependencies]
roup = { git = "https://github.com/ouankou/roup.git" }

2. Parse Your First Directive

use roup::parser::openmp::parse_openmp_directive;
use roup::lexer::Language;

fn main() {
    let input = "#pragma omp parallel for num_threads(4)";
    
    match parse_openmp_directive(input, Language::C) {
        Ok(directive) => {
            println!("✓ Successfully parsed: {:?}", directive.kind);
            println!("  Clauses: {}", directive.clauses.len());
            
            for clause in &directive.clauses {
                println!("  - {:?}", clause);
            }
        }
        Err(e) => {
            eprintln!("✗ Parse error: {}", e);
        }
    }
}

3. Run

cargo run

Output:

✓ Successfully parsed: ParallelFor
  Clauses: 1
  - NumThreads(Expr { value: "4", .. })

Next: See the Rust Tutorial for advanced usage.


Quick Start: C

1. Write Your Program

The C API uses direct pointers (malloc/free pattern):

#include <stdio.h>
#include <stdint.h>

// Forward declarations from libroup
typedef struct OmpDirective OmpDirective;

OmpDirective* roup_parse(const char* input);
int32_t roup_directive_clause_count(const OmpDirective* dir);
void roup_directive_free(OmpDirective* dir);

int main() {
    // Parse a directive
    OmpDirective* directive = roup_parse("#pragma omp parallel num_threads(4)");
    
    if (!directive) {
        fprintf(stderr, "Parse failed\n");
        return 1;
    }
    
    // Query clause count
    int32_t count = roup_directive_clause_count(directive);
    printf("Clause count: %d\n", count);
    
    // Clean up
    roup_directive_free(directive);
    
    return 0;
}

2. Compile

# Build ROUP library first
cargo build --release

# Compile your C program
clang example.c \
  -L./target/release \
  -lroup \
  -lpthread -ldl -lm \
  -Wl,-rpath,./target/release \
  -o example

On macOS:

clang example.c \
  -L./target/release \
  -lroup \
  -lpthread -ldl \
  -Wl,-rpath,@executable_path/../target/release \
  -o example

3. Run

./example

Output:

Clause count: 1

Next: See the C Tutorial for complete examples with iteration and error handling.


Quick Start: C++

1. Create Your Program

Modern C++17 with RAII wrappers:

#include <iostream>
#include <cstdint>

// Forward declarations from libroup C API
struct OmpDirective;
extern "C" {
    OmpDirective* roup_parse(const char* input);
    int32_t roup_directive_clause_count(const OmpDirective* dir);
    void roup_directive_free(OmpDirective* dir);
}

// Simple RAII wrapper
class Directive {
    OmpDirective* ptr_;
public:
    explicit Directive(const char* input) 
        : ptr_(roup_parse(input)) {}
    
    ~Directive() {
        if (ptr_) roup_directive_free(ptr_);
    }
    
    // Delete copy, allow move
    Directive(const Directive&) = delete;
    Directive& operator=(const Directive&) = delete;
    Directive(Directive&& other) noexcept 
        : ptr_(other.ptr_) {
        other.ptr_ = nullptr;
    }
    
    bool valid() const { 
        return ptr_ != nullptr; 
    }
    
    int clause_count() const {
        return ptr_ ? roup_directive_clause_count(ptr_) : 0;
    }
};

int main() {
    Directive dir("#pragma omp parallel for num_threads(4)");
    
    if (!dir.valid()) {
        std::cerr << "Parse failed\n";
        return 1;
    }
    
    std::cout << "Clause count: " << dir.clause_count() << "\n";
    
    return 0;
}  // Automatic cleanup via RAII

2. Compile

# Build ROUP library first
cargo build --release

# Compile your C++ program
clang++ -std=c++17 example.cpp \
  -L./target/release \
  -lroup \
  -lpthread -ldl -lm \
  -Wl,-rpath,./target/release \
  -o example

3. Run

./example

Output:

Clause count: 1

Next: See the C++ Tutorial for a complete real-world example.


What's Supported?

Directives (95 total)

✅ Parallelism: parallel, for, sections, single, master
✅ Tasking: task, taskwait, taskgroup, taskloop
✅ Device offloading: target, teams, distribute
✅ Synchronization: barrier, critical, atomic
✅ Advanced: metadirective, declare variant, loop

Clauses (91 total)

✅ Scheduling: schedule, collapse, ordered
✅ Data-sharing: private, shared, firstprivate, lastprivate
✅ Reductions: reduction(+|-|*|&|&&|min|max:vars)
✅ Device clauses: device, map, is_device_ptr
✅ Control: if, num_threads, default

For the complete support matrix, see OpenMP Support.


Troubleshooting

Library Not Found at Runtime

Linux:

export LD_LIBRARY_PATH=$PWD/target/release:$LD_LIBRARY_PATH
./example

Or use -Wl,-rpath during compilation (recommended):

clang example.c -L./target/release -lroup -lpthread -ldl -lm -Wl,-rpath,$PWD/target/release

macOS:

export DYLD_LIBRARY_PATH=$PWD/target/release:$DYLD_LIBRARY_PATH
./example

Parse Returns NULL

Check your OpenMP syntax:

// ✅ Valid
OmpDirective* dir = roup_parse("#pragma omp parallel");

// ✅ Valid - with clauses
dir = roup_parse("#pragma omp parallel num_threads(4)");

// ❌ Invalid - missing 'omp'
dir = roup_parse("#pragma parallel");  // Returns NULL

Always check for NULL:

OmpDirective* dir = roup_parse(input);
if (!dir) {
    fprintf(stderr, "Parse error\n");
    return 1;
}
// ... use dir ...
roup_directive_free(dir);

C++ Compilation Errors

Make sure you're using C++17:

# ✅ Correct
clang++ -std=c++17 example.cpp ...

# ❌ Wrong - C++11 lacks required features
clang++ -std=c++11 example.cpp ...

Next Steps

Learn More

Examples

  • examples/c/ - 5 complete C examples
  • examples/cpp/ - 3 complete C++ examples with RAII

Advanced Topics

  • Error handling strategies
  • Iterator patterns for clauses
  • Thread safety considerations
  • Performance optimization

Summary

Rust:

cargo add roup
# Write code, then:
cargo run

C:

cargo build --release
clang example.c -L./target/release -lroup -lpthread -ldl -lm -Wl,-rpath,./target/release
./example

C++:

cargo build --release
clang++ -std=c++17 example.cpp -L./target/release -lroup -lpthread -ldl -lm -Wl,-rpath,./target/release
./example

You're ready to experiment with OpenMP parsing! 🎉