Commit aaaebe0c authored by Cianciosa, Mark's avatar Cianciosa, Mark
Browse files

Merge branch 'documentation' into 'main'

Complete Doxygen documentation

See merge request !79
parents 15e8ab0f 022953fa
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -310,6 +310,8 @@ if (DOXYGEN_FOUND)
    set (DOXYGEN_PROJECT_NAME "Graph Framework")
    set (DOXYGEN_EXCLUDE ${CMAKE_CURRENT_SOURCE_DIR}/LLVM ${CMAKE_CURRENT_SOURCE_DIR}/build)
    set (DOXYGEN_GENERATE_TREEVIEW YES)
    set (DOXYGEN_USE_MATHJAX YES)
    set (DOXYGEN_IMAGE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/graph_docs)

    doxygen_add_docs (doc)
endif ()
+16 −48
Original line number Diff line number Diff line
# graph_framework
# Quick Start Guide

Graph computation framework that supports auto differentiation.
**graph_framework**: A graph computation framework that supports auto 
differentiation. It is designed to allow domain scientists to create cross 
platform GPU accelerated code and embed those codes in existing legacy tools.

# Dependencies
This code makes use of the [NetCDF `C` library](https://www.unidata.ucar.edu/software/netcdf/).

On Macs, this requires the latest install of XCode 16.3.

# Compiling
To compile the code, first clone this repository.

A `graph_framework` directory will be created. In this directory create 
a `build` directory and navigate to it.

```
cd graph_framework
mkdir build
cd build
```

It's recommended that you use the `ccmake` to configure the build system. 
From inside the build directory, run the `ccmake` command
## Documentation
[graph_framework-docs](https://ornl-fusion.github.io/graph_framework-docs) 
Documentation for the graph_framework.

## Obtaining the Code
To get started clone this repository using the command.
```
ccmake ../
git clone https://github.com/ORNL-Fusion/graph_framework.git
```

Initally, there will be no options. Press the `c` key to configure. 
During this step, the LLVM software repo is cloned and configured. 
This may take a while. Once configured, there will be several options.

- On Linux systems, you may optionally use CUDA by toggling the `USE_CUDA` 
option.
- On Mac systems, you may optionally use Metal by toggling the `USE_METAL`
option. 

__NOTE__: On Macs using the default system compiler, you will need to change 
the `CMAKE_CXX_COMPILER` to `clang++`. To do this press the `t` to toggle
to the advanced options.

Once all the options are configured press the 'c' key again and a 
generate 'g' option will be available. Pressing the 'g' key will finish
generating the make file and close out `ccmake`.

One the makefile is created. The code can be built using `make` or 
optionally built in parallel using `make -j'_[number of parallel intances]_.

__NOTE__: To many parallel instances can cause the LLVM build system to
hang so it is recommended to limit these to less than 20 depending on
the available memory.

Unit tests can be run by the `make test` command. An example ray tracing
case can be found in `efit_example.sh` of the `graph_driver` directory.
## Compiling the Code
For instructions to build the code consult the 
[build system](https://ornl-fusion.github.io/graph_framework-docs/build_system.html)
documentation. This framework uses a [cmake](https://cmake.org) based build 
system and requires the [NetCDF-C](https://www.unidata.ucar.edu/software/netcdf/)
library.
+4 −4
Original line number Diff line number Diff line
@@ -38,10 +38,10 @@ void bench_runner() {
    const size_t batch = NUM_RAYS/threads.size();
    const size_t extra = NUM_RAYS%threads.size();

    timeing::measure_diagnostic_threaded time_setup("Setup Time");
    timeing::measure_diagnostic_threaded time_init("Init Time");
    timeing::measure_diagnostic_threaded time_compile("Compile Time");
    timeing::measure_diagnostic_threaded time_steps("Time Steps");
    timing::measure_diagnostic_threaded time_setup("Setup Time");
    timing::measure_diagnostic_threaded time_init("Init Time");
    timing::measure_diagnostic_threaded time_compile("Compile Time");
    timing::measure_diagnostic_threaded time_steps("Time Steps");

    for (size_t i = 0, ie = threads.size(); i < ie; i++) {
        threads[i] = std::thread([&time_setup, &time_init, &time_compile, &time_steps, batch, extra] (const size_t thread_number) -> void {
+1 −1
Original line number Diff line number Diff line
@@ -1127,7 +1127,7 @@ extern "C" {
///
///  @param[in] c   The graph C context.
///  @param[in] arg The left opperand.
///  @returns sin(arg)
///  @returns cos(arg)
//------------------------------------------------------------------------------
    graph_node graph_cos(STRUCT_TAG graph_c_context *c,
                         graph_node arg) {
+119 −0
Original line number Diff line number Diff line
@@ -2,6 +2,111 @@
///  @file graph_c_binding.h
///  @brief Header file for the c binding library.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
///  @page graph_c_binding Embedding in C code
///  @brief Documentation for linking into a C code base.
///  @tableofcontents
///
///  @section graph_c_binding_into Introduction
///  This section assumes the reader is already familar with developing C codes.
///  The simplist method to link framework code into a C code is to create a C++
///  function with @code extern "C" @endcode First create a header file
///  <tt><i>c_callable</i>.h</tt>
///  @code
///  extern "C" {
///      void c_callable_function();
///  }
///  @endcode
///
///  Next create a source file <tt><i>c_callable</i>.c</tt> and add the
///  framework. This example uses the equation of a line example from the 
///  @ref tutorial_workflow "making workflows" turorial.
///  @code
///  //  Include the necessary framework headers.
///
///  extern "C" {
///      void c_callable_function() {
///          auto x = graph::variable(3, "x");
///
///  // Define explicit constant.
///          auto m = graph::constant<T> (0.4);
///  // Define implicit constant.
///          const T b = 0.6;
///
///  // Equation of a line
///          auto y = m*x + b;
///
///  // Auto differentiation.
///          auto dydx = y->df(x);
///
///          x->set({1.0, 2.0, 3.0});
///
///  // Create a workflow manager.
///          workflow::manager<T> work(0);
///          work.add_item({
///              graph::variable_cast(x)
///          }, {
///              y, dydx
///          }, {}, NULL, "my_first_kernel", 3);
///          work.compile();
///
///          work.run();
///          work.print(0, {x, y, dydx});
///          work.print(1, {x, y, dydx});
///          work.print(2, {x, y, dydx});
///      }
///  }
///  @endcode
///
///  <hr>
///  @section graph_c_binding_interface C Binding Interface
///  An alternative is to use the @ref graph_c_binding.h "C Language interface".
///  The C binding interface can be enabled as one of the <tt>cmake</tt>
///  @ref build_system_user_options "conifgure options". As an example, we will
///  convert the @ref tutorial_workflow "making workflows" turorial to use the
///  C language bindings.
///  @code
///  #include <graph_c_binding.h>
///
///  void c_binding() {
///      const bool use_safe_math = 0;
///      struct graph_c_context *c_context = graph_construct_context(DOUBLE, use_safe_math);
///      graph_node x = graph_variable(c_context, 3, "x");
///
///      graph_node m = graph_constant(c_context, 0.4);
///      graph_node b = graph_constant(c_context, 0.6);
///
///      graph_node y = graph_add(c_context, graph_mul(c_context, m, x), b);
///      graph_node dydx = graph_df(c_context, y, x);
///
///      double temp[3];
///      temp[0] = 1.0;
///      temp[1] = 2.0;
///      temp[2] = 3.0;
///      graoh_set_variable(c_context, x, temp);
///
///      graph_set_device_number(c_context, 0);
///      graph_node inputs[1];
///      inputs[0] = x;
///      graph_node outputs[2];
///      outputs[0] = y;
///      outputs[1] = dydx;
///      graph_add_item(c_context, inputs, 1, outputs, 2, NULL, NULL, 0, NULL,
///                     "x", 3);
///      graph_compile(c_context);
///      graph_run(c_context);
///      graph_node inputs2[3];
///      inputs2[0] = x;
///      inputs2[1] = y;
///      inputs2[2] = dydx;
///      graph_print(c_context, 0, inputs2, 3);
///      graph_print(c_context, 1, inputs2, 3);
///      graph_print(c_context, 2, inputs2, 3);
///
///      graph_destroy_context(c_context);
///  }
///  @endcode
//------------------------------------------------------------------------------

#ifndef graph_c_binding_h
#define graph_c_binding_h
@@ -10,6 +115,16 @@
#include <stdint.h>
#include <stdbool.h>

//------------------------------------------------------------------------------
///  @def START_GPU
///  Starts a Cocoa auto release pool when using the metal backend. No opt
///  otherwise.
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
///  @def END_GPU
///  Ends a Cocoa auto release pool when using the metal backend. No opt
///  otherwise.
//------------------------------------------------------------------------------
#ifdef USE_METAL
#define START_GPU @autoreleasepool {
#define END_GPU }
@@ -18,6 +133,10 @@
#define END_GPU
#endif

//------------------------------------------------------------------------------
///  @def STRUCT_TAG
///  C++ mode needs to tag a graph_c_context as a struct.
//------------------------------------------------------------------------------
#ifdef __cplusplus
extern "C" {
#define STRUCT_TAG
Loading