Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rework Codelet to be more similar to C++ API #9

Open
vchuravy opened this issue Mar 13, 2023 · 8 comments
Open

Rework Codelet to be more similar to C++ API #9

vchuravy opened this issue Mar 13, 2023 · 8 comments
Labels
code generation Related to GPUCompiler code generation infrastructure enhancement New feature or request

Comments

@vchuravy
Copy link
Collaborator

vchuravy commented Mar 13, 2023

struct MyVertex <: Vertex
  in::PopVec
  out::PopVec
end
function (vertex::MyVertex)()
   vertex.out .= vertex.in
end

According the the docs the ABI is:

int __runCodelet_MyVertex() {

  void *vertexPtr = __builtin_colossus_get_vertex_base();
  auto v = static_cast<MyVertex*>(vertexPtr);
  return v->compute();
}

We could codegen that __runCodlet function.
@llvm.colossus.get.vertex.base() is the intrinsic to get the vector base.

The big unknown is how to do the mapping from Julia fields to input and output in the poplar graph.

There is an inspector https://docs.graphcore.ai/projects/poplar-api/en/latest/poplar/graph/VertexIntrospector.html#_CPPv4N6poplar18VertexIntrospectorE

So the question is how popc generates the mapping

@giordano giordano added code generation Related to GPUCompiler code generation infrastructure enhancement New feature or request labels Mar 13, 2023
@vchuravy
Copy link
Collaborator Author

vchuravy commented Mar 13, 2023

There is a very interest method:

/**
 * Generate a string representation of a Vertex type for use by
 * poplar::Graph::addVertex().
 *
 * \param name  The name of the vertex.
 * \param args  The types of the arguments to the vertex.
 * \return      A string representation of the vertex type.
 */
template <typename... Args>
inline std::string templateVertex(const std::string &name, Args &&...args) {
  return name + templateVertexParams(true, std::forward<Args>(args)...);
}

That makes it sound like there is an extended addVertex function.

https://github.com/graphcore/tensorflow/blob/2b7af067dae32b210a8d1f053d1aec5f3722e[…]e8d/tensorflow/compiler/plugin/poplar/driver/vertex_templates.h

@vchuravy
Copy link
Collaborator Author

So I propose the following experiment:

graph.addCodelets("vectorAdd.ll", CodeletFileType::IrSource)
vectorAddCS = graph.addComputeSet(poputil::templateVertex("VectorAdd"), args...);

@giordano
Copy link
Collaborator

For the record, I applied

diff --git a/feature_examples/poplar/advanced_example/Makefile b/feature_examples/poplar/advanced_example/Makefile
index b899c2f..1d59c1b 100644
--- a/feature_examples/poplar/advanced_example/Makefile
+++ b/feature_examples/poplar/advanced_example/Makefile
@@ -1,12 +1,15 @@
 CC = g++
 
-all: codelets.gp example
+all: example
 
 codelets.gp: codelets.cpp
-	popc codelets.cpp -o codelets.gp
+	popc $^ -o $@
 
-example: utils.h main.cpp
-	$(CC) --std=c++11 main.cpp -o example -lpoplar -lpopops -lboost_program_options
+codelets.ll: codelets.cpp
+	popc --emit-llvm -target ipu2 $^ -o $@
+
+example: main.cpp utils.h codelets.ll
+	$(CC) --std=c++11 $< -o $@ -lpoplar -lpopops -lboost_program_options
 
 clean:
-	rm codelets.gp example
+	rm -f codelets.ll codelets.gp example
diff --git a/feature_examples/poplar/advanced_example/main.cpp b/feature_examples/poplar/advanced_example/main.cpp
index 505fe38..dfe540d 100644
--- a/feature_examples/poplar/advanced_example/main.cpp
+++ b/feature_examples/poplar/advanced_example/main.cpp
@@ -39,7 +39,7 @@ buildGraphAndPrograms(poplar::Graph &g, const utils::Options &options) {
   // Before we can add a custom vertex to the graph we need to load its
   // code. NOTE: .gp files are precompiled codelets but we could also
   // have loaded and compiled source directly here:
-  g.addCodelets("codelets.gp"); // g.addCodelets("codelets.cpp");
+  g.addCodelets("codelets.ll"); // g.addCodelets("codelets.cpp");
   auto v = g.addVertex(cs1, "VectorAdd");
 
   // Vertices must also be mapped to tiles. This computation will

to https://github.com/graphcore/tutorials/tree/b7ffa4de24e07efbeda2e3241ea46d20fa119b84, and ran

make && ./example

in feature_examples/poplar/advanced_example, but I got

Using HW device ID: 0
warning: argument unused during compilation: '-isystem /cm/shared/apps/graphcore/sdk/3.0.0/lib/graphcore/include'
warning: argument unused during compilation: '-isystem /cm/shared/apps/graphcore/sdk/3.0.0/lib/graphcore/include/c++'
warning: argument unused during compilation: '-isystem /cm/shared/apps/graphcore/sdk/3.0.0/lib/clang/15.0.0/include'
warning: argument unused during compilation: '-isystem /cm/shared/apps/graphcore/sdk/3.0.0/lib/graphcore/include/poplar'
warning: argument unused during compilation: '-isystem /cm/shared/apps/graphcore/sdk/3.0.0/include'
warning: argument unused during compilation: '-I .'
6 warnings generated.
Exception: Unknown vertex type 'VectorAdd (In addVertex for Compute Set cs1).'

I was told in Graphcore Slack that this might be bug. Tried with both Poplar SDK v2.5 and v3.0.

@vchuravy
Copy link
Collaborator Author

Can you try passing CodeletFileType::IrSource directly?

@giordano
Copy link
Collaborator

I tried that, and it didn't change much. According to addCodelets docstring the codelet type is inferred from the extension by default (CodeletFileType::Auto)

@giordano
Copy link
Collaborator

For the record, I was told that to add a codelet implemented purely in LLVM IR we may have to use addCodeletPlaceholder, to provide extra information which is automatically inferred from the C++ class.

@vchuravy
Copy link
Collaborator Author

Oh neat! That was the function I was looking for. That makes sense to me since I was wondering how the mapping from graph to arguments worked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
code generation Related to GPUCompiler code generation infrastructure enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants