6 Star 9 Fork 3


Create your Gitee Account
Explore and code with more than 12 million developers,Free private repositories !:)
Sign up
Clone or Download
Sync branch
Notice: Creating folder will generate an empty file .keep, because not support in Git
   _____  .____   __________
  /  _  \ |    |  \______   \
 /  /_\  \|    |   |     ___/
/    |    \    |___|    |
\____|__  /_______ \____|
        \/        \/

  Copyright 2021 Huawei Technologies Co., Ltd.

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


Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
See the License for the specific language governing permissions and
limitations under the License.

This distribution contains the C++ Algebraic Programming (ALP) framework, and provides the ALP/GraphBLAS, ALP/Pregel, and Sparse BLAS programming interfaces. Only a subset of Sparse BLAS functionality is supported, at present.

This distribution contains ALP backends that generate:

  • sequential programs,
  • shared-memory auto-parallelised programs,
  • nonblocking shared-memory auto-parallelised programs, and
  • sequential programs that generate HyperDAG representations of the executed ALP program.

Additional backends may optionally be enabled by providing their dependences. Those backends generate:

  • distributed-memory auto-parallelised programs,
  • hybrid shared- and distributed-memory auto-parallelised programs, and
  • sequential programs for the Banshee RISC-V Snitch Core simulator (experimental).

All backends perform automatically generate vectorised programs, amongst other automatically-applied optimisations.

The ALP/GraphBLAS and ALP/Pregel interfaces are enabled for all backends, while the standard Sparse BLAS APIs only allow for the efficient support of the sequential and shared-memory parallel backends.

Minimal requirements

We first summarise the compile-time, link-time, and run-time dependences of ALP. The following are required for producing both sequential and shared-memory ALP libraries and programs, using its reference and reference_omp backends.


To compile ALP, you need the following tools:

  1. A C++11-capable compiler such as GCC 4.8.2 or higher, with OpenMP support
  2. LibNUMA development headers
  3. POSIX threads development headers
  4. CMake version 3.13 or higher, with GNU Make (CMake's default build tool on UNIX systems) or any other supported build tool.

Linking and run-time

The ALP libraries link against the following libraries:

  1. LibNUMA: -lnuma
  2. Standard math library: -lm
  3. POSIX threads: -lpthread
  4. OpenMP: -fopenmp in the case of GCC

Optional dependences

The below summarises the dependences for optional features.

Distributed-memory auto-parallelisation

For distributed-memory parallelisation, the Lightweight Parallel Foundations (LPF) communication layer, version 1.0 or higher, is required. ALP makes use of the LPF core library and its collectives library. The LPF library has its further dependences, which are all summarised on the LPF project page:

The dependence on LPF applies to compilation, linking, and run-time. Fulfilling the dependence enables the bsp1d and hybrid ALP/GraphBLAS backends.

Code documentation

For generating the code documentations:

  • doxygen reads code comments and generates the documentation;
  • graphviz generates various diagrams for inheritance, call paths, etc.;
  • pdflatex is required to build the PDF file out of the Latex generated documentation.

Very quick start

Here are example steps to compile and install ALP for shared-memory machines without distributed-memory support. The last three commands show-case the compilation and execution of the sp.cpp example program.

cd <ALP/root/dir>
mkdir build
cd build
../bootstrap.sh --prefix=../install
make -j
make -j install
source ../install/bin/setenv
grbcxx ../examples/sp.cpp
grbrun ./a.out

Quick start

In more detail, the steps to follow are:

  1. Edit the include/graphblas/base/config.hpp. In particular, please ensure that config::SIMD_SIZE::bytes defined in that file is set correctly with respect to the target architecture.

  2. Create an empty directory for building ALP and move into it: mkdir build && cd build.

  3. Invoke the bootstrap.sh script located inside the ALP root directory <ALP/root/dir> to generate the build infrastructure via CMake inside the the current directory:

    <ALP/root/dir>/bootstrap.sh --prefix=</path/to/install/dir>

    • note: add --with-lpf=/path/to/lpf/install/dir if you have LPF installed and would like to use it.
  4. Issue make -j to compile the C++11 ALP library for the configured backends.

  5. (Optional) To later run all unit tests, several datasets must be made available. Please run the <ALP/root/dir>/tools/downloadDatasets.sh script for

    a. an overview of datasets required for the basic tests, as well as

    b. the option to automatically download them.

  6. (Optional) To make the ALP documentation, issue make userdocs. This generates both

    a. LaTeX in <ALP build dir>/docs/user/latex/refman.tex, and

    b. HTML in <ALP build dir>/docs/user/html/index.html.

    To build a PDF from the LaTeX sources, cd into the directory mentioned, and issue make.

  7. (Optional) Issue make -j smoketests to run a quick set of functional tests. Please scan the output for any failed tests. If you do this with LPF enabled, and LPF was configured to use an MPI engine (which is the default), and the MPI implementation used is not MPICH, then the default command lines the tests script uses are likely wrong. In this case, please edit tests/parse_env.sh by searching for the MPI implementation you used, and uncomment the lines directly below each occurrence.

  8. (Optional) Issue make -j unittests to run an exhaustive set of unit tests. Please scan the output for any failed tests. If you do this with LPF enabled, please edit tests/parse_env.sh if required as described in step 5.

  9. Issue make -j install to install ALP into the install directory configured during step 1.

  10. (Optional) Issue source </path/to/install/dir>/bin/setenv to make available the grbcxx and grbrun compiler wrapper and runner.

Congratulations, you are now ready for developing and integrating ALP algorithms! Any feedback, question, problem reports are most welcome at

Additional Contents

The remainder of this file summarises configuration options, additional build system targets, how to integrate ALP programs into applications, debugging, and contribute to ALP development. Finally, this README acknowledges contributors and lists technical papers.


ALP employs configuration headers that contain constexpr settings that take effect every time ALP programs are compiled. Multiple object files that were compiled using ALP must all been compiled using the same configuration settings-- linking objects that have been compiled with a mixture of configurations are likely to incur undefined behaviour. The recommendation is to set a configuration before building and installing ALP, and to keep the installation directories read-only so that configurations remain static.

There exists one main configuration file that affects all ALP backends, while other configuration files only affect a specific backend or only affect specific classes of backends. The main configuration file is found in <root>/include/graphblas/base/config.hpp, which allows one to set the

  1. cache line size, in bytes, within the CACHE_LINE_SIZE class;
  2. SIMD width, in bytes, within the SIMD_SIZE class;
  3. default number of experiment repetitions during benchmarking, within the BENCHMARKING class;
  4. L1 data cache size, in bytes, within MEMORY::big_memory class;
  5. from which size onwards memory allocations will be reported, in log-2 bytes, within MEMORY::big_memory;
  6. index type used for row coordinates, as the RowIndexType typedef;
  7. index type used for column coordinates, as the ColIndexType typedef;
  8. type used for indexing nonzeroes, as the NonzeroIndexType typedef;
  9. index type used for vector coordinates, as the VectorIndexType typedef.

Other configuration values in this file are automatically inferred, are fixed non-configurable settings, or are presently not used by any ALP backend.

Reference and reference_omp backends

The file include/graphblas/reference/config.hpp contain defaults that pertain to the auto-vectorising and sequential reference backend, but also to the shared-memory auto-parallelising reference_omp backend. It allows one to set

  1. whether prefetching is enabled in PREFETCHING::enabled;
  2. the prefetch distance in PREFETCHING::distance;
  3. the default memory allocation strategy for thread-local data in IMPLEMENTATION::defaultAllocMode();
  4. same, but for shared data amongst threads in IMPLEMENTATION::sharedAllocMode();

Modifying any of the above should be done with utmost care as it typically affects the defaults across an ALP installation, and all programs compiled using it. Configuration elements not mentioned here should not be touched by users, and rather should concern ALP developers only.

OpenMP backends

The file include/graphblas/omp/config.hpp contains some basic configuration parameters that affect any OpenMP-based backend. However, the configuration file does not contain any other user-modifiable settings, but rather contains a) some utilities that OpenMP-based backends may rely on, and b) default that are derived from other settings described in the above. These settings should only be overridden with compelling and expert knowledge.

LPF backends

The file include/graphblas/bsp/config.hpp contains some basic configuration parameters that affect any LPF-based backend. It includes:

  1. an initial maximum of LPF memory slot registrations in LPF::regs();
  2. an initial maximum of LPF messages in LPF::maxh().

These defaults, if insufficient, will be automatically resized during execution. Setting these large enough will therefore chiefly prevent buffer resizes at run- time. Modifying these should normally not lead to significant performance differences.


The file include/graphblas/utils/config.hpp details configurations of various utility functions, including:

  1. a buffer size used during reading input files, in PARSER::bsize();
  2. the block size of individual reads in PARSER::read_bsize().

These defaults are usually fine except when reading from SSDs, which would benefit of a larger read_bsize.


While there are various other configuration files (find config.hpp), the above should list all user-modifiable configuration settings of interest. The remainder pertain to configurations that are automatically deduced from the aforementioned settings, or pertain to settings that describe how to safely compose backends and thus only are of interest to ALP developers.

Overview of the main Makefile targets

The following table lists the main build targets of interest:

Target Explanation
[default] builds the ALP libraries and examples, including
Sparse BLAS libraries generated by ALP
install install libraries, headers and some convenience
scripts into the path set via --prefix=<path>
unittests builds and runs all available unit tests
smoketests builds and runs all available smoke tests
perftests builds and runs all available performance tests
tests builds and runs all available unit, smoke, and
performance tests
userdocs builds HTML and LaTeX documentation corresponding
to the public ALP API
devdocs builds HTML and LaTeX code documentation for
developers of the ALP internals
docs build both the user and developer code

For more information about the testing harness, please refer to the related documentation.

For more information on how the build and test infrastructure operate, please refer to the the related documentation.

Automated performance testing

To check in-depth performance of this ALP implementation, issue make -j perftests. This will run several algorithms in several ALP configurations. This generates three main output files:

  1. <ALP/build/dir>/tests/performance/output, which summarises the whole run;

  2. <ALP/build/dir>/tests/performance/output/benchmarks, which summarises the performance of individual algorithms; and

  3. <ALP/build/dir>/tests/performance/output/scaling, which summarises operator scaling results.

To ensure that all tests run, please ensure that all related datasets are available, as also described at step 5 of the quick start.

With LPF enabled, please note the remark described at steps 3 and 7 of the quick start guide. If LPF was not configured using MPICH, please review and apply any necessary changes to tests/performance/performancetests.sh.

Integrating ALP with applications

There are several use cases in which ALP can be deployed and utilised, listed in the following. These assume that the user has installed ALP in a dedicated directory via make install.

Running ALP programs as standalone executables


The grb::Launcher< AUTOMATIC > class abstracts a group of user processes that should collaboratively execute any single ALP program. The ALP program of interest must have the following signature:

void grb_program( const T& input_data, U& output_data )

The types T and U can be any plain-old-data (POD) type, including structs -- these can be used to broadcast input data from the master process to all user processes (input_data) -- and for data to be sent back on exit of the parallel ALP program.

The above sending-and-receiving across processes applies only to ALP implementations and backends that support or require multiple user processes; both the sequential reference and the shared-memory parallel reference_omp backends, for example, support only one user process.

In case of multiple user processes, the overhead of the broadcasting of input data is linear in the number of user processes, as well as linear in the byte- size of T which hence should be kept to a minimum. A recommended use of this mechanism is, e.g., to broadcast input data locations; any additional I/O should use the parallel I/O mechanisms that ALP exposes to the ALP program itself.

Output data is retrieved only from the user process with ID 0, even if multiple user processes exist. Some implementations or systems may require sending back the output data to a calling process, even if there is only one user process. The data movement cost incurred should hence be considered linear in the byte size of U, and, similar to the input data broadcasting, the use of parallel I/O facilities from the ALP program itself for storing large outputs is strongly advisable.


Our backends auto-vectorise, hence please recall step 1 from the quick start guide, and make sure the include/graphblas/base/config.hpp file reflects the correct value for config::SIMD_SIZE::bytes. This value must be updated prior to the compilation and installation of ALP.

When targeting different architectures with differing SIMD widths, different ALP installations for different architectures could be maintained.

ALP programs may be compiled using the compiler wrapper grbcxx that is generated during installation. To compile high-performance code when compiling your programs using the ALP installation, the following flags are recommended:

  • -DNDEBUG -O3 -mtune=native -march=native -funroll-loops

Omitting these flags for brevity, some compilation examples follow.

When using the LPF-enabled hybrid shared- and distributed-memory ALP backends,

grbcxx -b hybrid

as the compiler command. To show all flags that the wrapper passes on, please use

grbcxx -b hybrid --show

and append your regular compilation arguments.

The hybrid backend is capable of spawning multiple ALP user processes. In contrast, compilation using

grbcxx -b reference

produces a sequential binary, while

grbcxx -b reference_omp

produces a shared-memory parallel binary.

Note that the ALP source code never requires change while switching backends.


The executable must be statically linked against an ALP library that is different depending on the selected backend. The compiler wrapper grbcxx takes care of all link-time dependencies automatically. When using the LPF-enabled BSP1D backend to ALP, for example, simply use grbcxx -b bsp1d as the compiler/linker command.


grbcxx -b bsp1d --show <your regular compilation command>

to show all flags that the wrapper passes on.


The resulting program has run-time dependencies that are taken care of by the LPF runner lpfrun or by the ALP runner grbrun.

We recommend using the latter:

grbrun -b hybrid -np <P> </path/to/my/program>

Here, P is the number of requested ALP user processes.


The hybrid backend employs threading in addition to distributed-memory parallelism. To employ threading to use all available hyper-threads or cores on a single node, the reference_omp backend may be selected instead.

In both cases, make sure that during execution the OMP_NUM_THREADS and OMP_PROC_BIND environment variables are set appropriately on each node that executes ALP user process(es).

Running parallel ALP programs from existing parallel contexts

This, instead of automatically spawning a requested number of user processes, assumes a number of processes already exist and that we wish those processes to jointly execute a single parallel ALP program.


The binary that contains the ALP program to be executed must define the following global symbol with the given value:


A program may then again be launched via the Launcher, but in this case the MANUAL template argument should be used instead. This specialisation disallows the use of a default constructor. Instead, construction requires four arguments as follows:

grb::Launcher< MANUAL > launcher( s, P, hostname, portname )

Here, P is the total number of processes that should jointly execute a parallel ALP program, while 0 <= s < P is a unique ID of this process amongst its P-1 siblings. The types of s and P are size_t, i.e., unsigned integers.

One of these processes must be selected as a connection broker prior to forming a group of ALP user processes. The remainder P-1 processes must first connect to the chosen broker using TCP/IP connections. This choice must be made outside of ALP, prior to setting up the launcher, and materialises as the hostname and portname Launcher constructor arguments. The host and port name are strings, and must be equal across all processes.

As before, and after the successful construction of a manual launcher instance, a parallel ALP program is launched via

grb::Launcher< MANUAL >::exec( &grb_program, input, output )

in exactly the same way as described earlier, though with the input and output arguments now being passed in a one-to-one fashion:

  1. The input data is passed on from the original process to exactly one corresponding ALP user process; i.e., no broadcast occurs. The original process and the ALP user process are, from an operating system point of view, the same process. Therefore, and additionally, input no longer needs to be a plain-old-data (POD) type. Pointers, for example, are now perfectly valid to pass along, and enable sharing data between the original process and the ALP algorithm.
  2. The output data is passed from each ALP user process to the original process that called Launcher< MANUAL >::exec. To share ALP vector data, it is, for example, legal to return a grb::PinnedVector< T > as the exec output argument type. Doing so is akin to returning a pointer to output data, and does not explicitly pack nor transmit vector data.


The pre-existing process must have been started using an external mechanism. This mechanism must include run-time dependence information that is normally passed by the ALP runner whenever a distributed-memory parallel backend is selected.

If the external mechanism by which the original processes are started allows it, this is most easily effected by using the standard grbcxx launcher while requesting only one process only, e.g.,

grbrun -b hybrid -n 1 </your/executable>

If the external mechanism does not allow this, then please execute e.g.

grbrun -b hybrid -n 1 --show </any/executable>

to inspect the run-time dependences and environment variables that must be made available, resp., set, as part of the external mechanism that spawns the original processes.

Integrating ALP within your coding project

Please see this article on how to add ALP and ALP/GraphBLAS as a dependence to your project.


To debug an ALP program, please compile it using the sequential reference backend and use standard debugging tools such as valgrind and gdb. Additionally, please ensure to not pass the -DNDEBUG flag during compilation.

If bugs appear in one backend but not another, it is likely you have found a bug in the former backend. Please send a minimum working example that demonstrates the bug to the maintainers, either as an issue on or an email to:

  1. GitHub;
  2. Gitee;
  3. Albert-Jan.

Development in ALP

Your contributions to ALP would be most welcome. Merge Requests (MRs) can be contributed via Gitee and GitHub; see above for the links.

For the complete development documentation, you should start from the docs/README file and the related Development guide.


The LPF communications layer was primarily authored by Wijnand Suijlen, without whom the current ALP would not be what it is now.

The collectives library and its interface to the ALP was primarily authored by Jonathan M. Nash.

The testing infrastructure that performs smoke, unit, and performance testing of sequential, shared-memory parallel, and distributed-memory parallel backends was primarily developed by Daniel Di Nardo.

ALP and ALP/GraphBLAS have since developed significantly, primarily through efforts by researchers at the Huawei Paris and Zürich Research Centres, and the Computing Systems Laboratory in Zürich in particular. See the NOTICE file for individual contributors.

Citing ALP, ALP/GraphBLAS, and ALP/Pregel

If you use ALP in your work, please consider citing one or more of the following papers, as appropriate.



Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] 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.


A C++ GraphBLAS interface that allows for the linear algebraic formulation of graph algorithms and more. It auto-optimises and auto-parallelises: you write the maths, the system does the rest! expand collapse
C++ and 5 more languages


No release




Load More
can not load any more
马建仓 AI 助手


344bd9b3 5694891 D2dac590 5694891