protocol buffers, again

91 views
Skip to first unread message

Krzysztof Sakrejda

unread,
Dec 4, 2015, 12:45:48 AM12/4/15
to stan development mailing list
I'm following up a little on a previous discussion[1], but I scaled down my ambitions to something that would let me play with Stan and protocol buffers without getting bogged down.

The goal this time around is to build a little I/O around stan::lang::compile so that a protobuf message can go in as input with the Stan program and a message can get returned with the C++ code. The protobuf version 2 file is attached, probably makes sense to use version 3 but Ubuntu doesn't have the protobuf compiler for that and the differences are minor.

I'm not proposing this as an addition to anything we have right now, but I'd like to go through and put it together in its own repo using boost::asio. Just looking for comments if you're interested.

Krzysztof

[1] https://groups.google.com/forum/#!searchin/stan-dev/IO/stan-dev/E1eYUI2FdYE/7d3kg8hcAwAJ

stanc.proto

Allen B. Riddell

unread,
Dec 4, 2015, 5:39:11 AM12/4/15
to stan...@googlegroups.com
This is specific task is perhaps more useful than you think. We need
some standard error format for other cases as well--e.g., when an
interface submits invalid parameters (e.g., some negative float for a
parameter that's strictly positive).

Is there any prior art on this? Perhaps someone has already thought hard
about standardizing a protobuf error message in this kind of situation?

I think opening an issue on Github might be the best place to have a
discussion on this. Or maybe starting a cmdstan-protobuf repository? (Or
pystan-protobuf or rstan-protobuf, depending on how you imagined
prototyping this.)

Best,

Allen
> --
> You received this message because you are subscribed to the Google Groups "stan development mailing list" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to stan-dev+u...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.


Krzysztof Sakrejda

unread,
Dec 4, 2015, 8:33:10 AM12/4/15
to stan development mailing list, a...@ariddell.org
On Friday, December 4, 2015 at 5:39:11 AM UTC-5, Allen B. Riddell wrote:
> This is specific task is perhaps more useful than you think. We need
> some standard error format for other cases as well--e.g., when an
> interface submits invalid parameters (e.g., some negative float for a
> parameter that's strictly positive).

I steered clear of this bigger issue for now because there's supposed to be a C++ API refactor that's going to address standardizing input facilities and past discussions have devolved into "protobuf vs. C++ API for Stan". I'll give it a shot anyway... I think Alan leaves this implicit but here's why the Stan C++ API discussion should also be a protobuf message type discussion:

1) protobuf provides multi-language mappings for strongly-typed language-agnostic data types (see the 'scalar value types' table in [1]).
2) protobuf provides strongly-typed language-agnostic complex types from message definitions.
3) protobuf auto-generates a _message_ API's that a library can be compatible with, but it's an auto-generated API with all the boilerplate that entails.

I think this sets protobuf apart in an API discussion from something that only deals with the format (e.g.-JSON) but at the same time it can't replace a well-formed C++ API. An important secondary benefit of having the protobuf discussion at the same time as the C++ API discussion would be involving the interface developers in deciding what works well for them without everyone having to have an opinion on the C++ API.

[1] https://developers.google.com/protocol-buffers/docs/proto3

> Is there any prior art on this? Perhaps someone has already thought hard
> about standardizing a protobuf error message in this kind of situation?

Good point, I was under-thinking this one. For inter-process (especially remote) communication using the protobuf rpc stuff would make sense[2,3]. The C++ API would be a lot less overhead when used locally but as you've pointed out that's not always easy.

I think it makes sense to stick to just stanc-related protobuf stuff for now and I can do a test-drive of how it would work with some of the grpc server examples once we agree on some preliminary message types.

[2] http://www.grpc.io/docs/
[3] https://github.com/grpc/grpc/blob/release-0_11/examples/cpp/cpptutorial.md

>
> I think opening an issue on Github might be the best place to have a
> discussion on this. Or maybe starting a cmdstan-protobuf repository? (Or
> pystan-protobuf or rstan-protobuf, depending on how you imagined
> prototyping this.)

I will start a github repo soon but I wanted to give the broader discussion here a shot first. I don't think I really got how protobuf could fit into Stan until it went around a few times on the dev list.

Krzysztof

Krzysztof Sakrejda

unread,
Dec 4, 2015, 8:38:23 AM12/4/15
to stan development mailing list, a...@ariddell.org
On Friday, December 4, 2015 at 8:33:10 AM UTC-5, Krzysztof Sakrejda wrote:
> I think Alan leaves this implicit but here's why ...

Wow, my name gets butchered often enough you'd think I would check spelling... sorry: Allen!

Krzysztof

Bob Carpenter

unread,
Dec 4, 2015, 1:20:48 PM12/4/15
to stan...@googlegroups.com
Agreed that some kind of protocol buffer I/O could be a useful
addition to Stan itself.

I'm not sure why Allen's bringing up error messages --- is
there something specific about protocol buffers for this use
case (as opposed to input data, output draws and adaptation
parameters, etc.)

The right layer to do this might be a parallel package to or
replacement package for CmdStan. I don't know how much we
want to drive this down to the Stan level. It'd be a good issue
to discuss at a meeting if we were all there.

- Bob

P.S. Please don't have discussions in GitHub issues. Keep them on
stan-dev or if you have a concrete design to discuss, a combination
of stan-dev and the Wiki. I'd like to keep the GitHub issues to
concrete issues.

Bob Carpenter

unread,
Dec 4, 2015, 1:29:38 PM12/4/15
to stan...@googlegroups.com, a...@ariddell.org

> On Dec 4, 2015, at 8:33 AM, Krzysztof Sakrejda <krzysztof...@gmail.com> wrote:
>
> On Friday, December 4, 2015 at 5:39:11 AM UTC-5, Allen B. Riddell wrote:
>> This is specific task is perhaps more useful than you think. We need
>> some standard error format for other cases as well--e.g., when an
>> interface submits invalid parameters (e.g., some negative float for a
>> parameter that's strictly positive).
>
> I steered clear of this bigger issue for now because there's supposed to be a C++ API refactor that's going to address standardizing input facilities and past discussions have devolved into "protobuf vs. C++ API for Stan".

This isn't a vs. thing so much as a layering issue.
I'm pretty sure we want to maintain a direct C++
data-structure interface at the API level.

Then a protocol buffer would be one way to implement
an input var_context (not refactored yet) or an
output_writer (in the middle of being refactored, I think).

> I'll give it a shot anyway... I think Alan leaves this implicit but here's why the Stan C++ API discussion should also be a protobuf message type discussion:
>
> 1) protobuf provides multi-language mappings for strongly-typed language-agnostic data types (see the 'scalar value types' table in [1]).

What's the type system? Is there an intro to protobuf types
I can read somewhere?

> 2) protobuf provides strongly-typed language-agnostic complex types from message definitions.

Could you ealborate on this. What's a "complex type"? You
mean like an array or a dictionary/hashmap/struct?

> 3) protobuf auto-generates a _message_ API's that a library can be compatible with, but it's an auto-generated API with all the boilerplate that entails.

I don't know what this means. You're thinking of something
that might go into a REST-ful server? Or something that'd
work through sockets in Docker?

> I think this sets protobuf apart in an API discussion from something that only deals with the format (e.g.-JSON) but at the same time it can't replace a well-formed C++ API.

I still don't see the conflict here.

> An important secondary benefit of having the protobuf discussion at the same time as the C++ API discussion would be involving the interface developers in deciding what works well for them without everyone having to have an opinion on the C++ API.
>
> [1] https://developers.google.com/protocol-buffers/docs/proto3

We should discuss all this together. I believe R and Python are
going to continue to interface in memory. Are you saying you'd
convert Python data structures to protocol buffers for consumption
by Stan? And then vice-versa? That's one way to do it, but it
seems like a wasted intermediate step.

>> Is there any prior art on this? Perhaps someone has already thought hard
>> about standardizing a protobuf error message in this kind of situation?
>
> Good point, I was under-thinking this one. For inter-process (especially remote) communication using the protobuf rpc stuff would make sense[2,3]. The C++ API would be a lot less overhead when used locally but as you've pointed out that's not always easy.
>
> I think it makes sense to stick to just stanc-related protobuf stuff for now and I can do a test-drive of how it would work with some of the grpc server examples once we agree on some preliminary message types.
>
> [2] http://www.grpc.io/docs/
> [3] https://github.com/grpc/grpc/blob/release-0_11/examples/cpp/cpptutorial.md

Stanc? As in the compiler? That seems like the thing least
in need of anything other than simple strings in and out with
error messages.

>> I think opening an issue on Github might be the best place to have a
>> discussion on this. Or maybe starting a cmdstan-protobuf repository? (Or
>> pystan-protobuf or rstan-protobuf, depending on how you imagined
>> prototyping this.)
>
> I will start a github repo soon but I wanted to give the broader discussion here a shot first. I don't think I really got how protobuf could fit into Stan until it went around a few times on the dev list.

Let's try to talk about this in a Stan meeting. I think we may just be
talking past each other in these emails.

- Bob


Allen B. Riddell

unread,
Dec 4, 2015, 1:37:10 PM12/4/15
to Krzysztof Sakrejda, stan development mailing list
Excellent summary. I'd add that protobuf can do zero-copy passing of
data between C++ and R/Python -- which is vital for calculating summary
statistics (including rhat) of large numbers of samples.

> > Is there any prior art on this? Perhaps someone has already thought
> > hard about standardizing a protobuf error message in this kind of
> > situation?
>
> Good point, I was under-thinking this one. For inter-process
> (especially remote) communication using the protobuf rpc stuff would
> make sense[2,3]. The C++ API would be a lot less overhead when used
> locally but as you've pointed out that's not always easy.
>
> I think it makes sense to stick to just stanc-related protobuf stuff
> for now and I can do a test-drive of how it would work with some of
> the grpc server examples once we agree on some preliminary message
> types.
>
> [2] http://www.grpc.io/docs/ [3]
> https://github.com/grpc/grpc/blob/release-0_11/examples/cpp/cpptutorial.md
>

Starting with an error message format from gRPC/similar sounds like a good idea.

> >
> > I think opening an issue on Github might be the best place to have a
> > discussion on this. Or maybe starting a cmdstan-protobuf repository?
> > (Or pystan-protobuf or rstan-protobuf, depending on how you imagined
> > prototyping this.)
>
> I will start a github repo soon but I wanted to give the broader
> discussion here a shot first. I don't think I really got how protobuf
> could fit into Stan until it went around a few times on the dev list.
>

Is there something standing in the way of creating a minimal
protobuf-shim on top of the current C++ API for stanc? This is where I
would start. I'd be willing to try this out with a fork/branch of
PyStan.

Having a working prototype would be a nice first step before we dig into
speccing out all the Messages.

Best,

Allen

Bob Carpenter

unread,
Dec 4, 2015, 1:56:41 PM12/4/15
to stan...@googlegroups.com
Zero-copy passing. How does that work? We need to
get std::vector and Eigen::Matrix instances on the Stan
side, both of which require copies from raw data
as far as I know. Now I can believe you could "zero copy"
a block of memory, like a pointer.

The only reason not to do this now is that it'll all change
again with the refactor, and I don't think Daniel or Michael
want more work for that. So as long as you're happy having it
on a branch until the Stan 3 refactor lands, there shouldn't
be a problem.

- Bob

Allen B. Riddell

unread,
Dec 4, 2015, 2:00:40 PM12/4/15
to stan...@googlegroups.com
On 12/04, Bob Carpenter wrote:
> Agreed that some kind of protocol buffer I/O could be a useful
> addition to Stan itself.
>
> I'm not sure why Allen's bringing up error messages --- is
> there something specific about protocol buffers for this use
> case (as opposed to input data, output draws and adaptation
> parameters, etc.)

Point taken; it's a bit tangential. This was the line of thinking: in
the stanc setting, dealing with error messages (parser errors) is
someone we do well with the current API. If we had a standard way of
reporting errors we could use it in other cases, e.g., when the
interface passed invalid algorithm parameters.

>
> The right layer to do this might be a parallel package to or
> replacement package for CmdStan. I don't know how much we
> want to drive this down to the Stan level. It'd be a good issue
> to discuss at a meeting if we were all there.
>

I think this is right. If it's a wild success perhaps Stan could adopt
it. Until then, some parallel package or shim layer makes sense.

> - Bob
>
> P.S. Please don't have discussions in GitHub issues. Keep them on
> stan-dev or if you have a concrete design to discuss, a combination
> of stan-dev and the Wiki. I'd like to keep the GitHub issues to
> concrete issues.

If we're going to comment on a file (e.g., the .proto file which was
attached to the email) -- we need to do it in Github because we can
comment on specific lines. It seems like we're already at that point.

Krzysztof Sakrejda

unread,
Dec 4, 2015, 2:30:53 PM12/4/15
to stan development mailing list, a...@ariddell.org
On Friday, December 4, 2015 at 1:29:38 PM UTC-5, Bob Carpenter wrote:

> > On Dec 4, 2015, at 8:33 AM, Krzysztof Sakrejda <@gmail.com> wrote:
> >
> > On Friday, December 4, 2015 at 5:39:11 AM UTC-5, Allen B. Riddell wrote:
> >> This is specific task is perhaps more useful than you think. We need
> >> some standard error format for other cases as well--e.g., when an
> >> interface submits invalid parameters (e.g., some negative float for a
> >> parameter that's strictly positive).
> >
> > I steered clear of this bigger issue for now because there's supposed to be a C++ API refactor that's going to address standardizing input facilities and past discussions have devolved into "protobuf vs. C++ API for Stan".
>
> This isn't a vs. thing so much as a layering issue.
> I'm pretty sure we want to maintain a direct C++
> data-structure interface at the API level.

Yes!

>
> Then a protocol buffer would be one way to implement
> an input var_context (not refactored yet) or an
> output_writer (in the middle of being refactored, I think).
>
> > I'll give it a shot anyway... I think Alan leaves this implicit but here's why the Stan C++ API discussion should also be a protobuf message type discussion:
> >
> > 1) protobuf provides multi-language mappings for strongly-typed language-agnostic data types (see the 'scalar value types' table in [1]).
>
> What's the type system? Is there an intro to protobuf types
> I can read somewhere?

Yes, look at the table of types in: https://developers.google.com/protocol-buffers/docs/proto3



> > 2) protobuf provides strongly-typed language-agnostic complex types from message definitions.
>
> Could you ealborate on this. What's a "complex type"? You
> mean like an array or a dictionary/hashmap/struct?

I was thinking struct. Look at any simple message definition, say:

message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
}

It's composed of types that have well-defined functions for construction/reading/writing in multiple languages but they can serve the same function as a 'struct' in a C program. They're also allowed to be nested.

>
> > 3) protobuf auto-generates a _message_ API's that a library can be compatible with, but it's an auto-generated API with all the boilerplate that entails.
>
> I don't know what this means. You're thinking of something
> that might go into a REST-ful server? Or something that'd
> work through sockets in Docker?

I think this is one of the hard things to get across---protobuf lets you define messages that we can use to talk about how interfaces _could_ communicate (yes, in a way that's inefficient if you can do in-memory instead and really more optimal for client-server interaction). What they _can't_ do is replace a good C++ Stan API so I think any protobuf thing should rely on stan-dev/stan rather than trying to integrate with it.


>
> > I think this sets protobuf apart in an API discussion from something that only deals with the format (e.g.-JSON) but at the same time it can't replace a well-formed C++ API.
>
> I still don't see the conflict here.

Ditto.

>
> > An important secondary benefit of having the protobuf discussion at the same time as the C++ API discussion would be involving the interface developers in deciding what works well for them without everyone having to have an opinion on the C++ API.
> >
> > [1] https://developers.google.com/protocol-buffers/docs/proto3
>
> We should discuss all this together. I believe R and Python are
> going to continue to interface in memory. Are you saying you'd
> convert Python data structures to protocol buffers for consumption
> by Stan? And then vice-versa? That's one way to do it, but it
> seems like a wasted intermediate step.

I think this is better for a meeting rather than email because there's a bunch of
different goals we won't really sort out in email. I think rstan/pystan are
mature enough that this discussion doesn't really touch on them but for many
other interface, especially just for prototyping interfaces and making them
easy to maintain it would be a good strategy.

>
> >> Is there any prior art on this? Perhaps someone has already thought hard
> >> about standardizing a protobuf error message in this kind of situation?
> >
> > Good point, I was under-thinking this one. For inter-process (especially remote) communication using the protobuf rpc stuff would make sense[2,3]. The C++ API would be a lot less overhead when used locally but as you've pointed out that's not always easy.
> >
> > I think it makes sense to stick to just stanc-related protobuf stuff for now and I can do a test-drive of how it would work with some of the grpc server examples once we agree on some preliminary message types.
> >
> > [2] http://www.grpc.io/docs/
> > [3] https://github.com/grpc/grpc/blob/release-0_11/examples/cpp/cpptutorial.md
>
> Stanc? As in the compiler? That seems like the thing least
> in need of anything other than simple strings in and out with
> error messages.

Agreed, but that also makes it the easiest place to do a proof of concept.

> >> I think opening an issue on Github might be the best place to have a
> >> discussion on this. Or maybe starting a cmdstan-protobuf repository? (Or
> >> pystan-protobuf or rstan-protobuf, depending on how you imagined
> >> prototyping this.)
> >
> > I will start a github repo soon but I wanted to give the broader discussion here a shot first. I don't think I really got how protobuf could fit into Stan until it went around a few times on the dev list.
>
> Let's try to talk about this in a Stan meeting. I think we may just be
> talking past each other in these emails.

Yep, I think the meetings tend to be scheduled at times I can make so let me know when it can be an agenda item.

>
> - Bob

Krzysztof Sakrejda

unread,
Dec 4, 2015, 2:39:18 PM12/4/15
to stan development mailing list, krzysztof...@gmail.com, a...@ariddell.org

Yeah, that's why I was thinking of just taking the available API for stanc because
it's just string -> string (with some other strings for messages). I like the stand-alone
idea because I don't understand pystan well, but it could be pystan.

>
> Best,
>
> Allen

Krzysztof Sakrejda

unread,
Dec 4, 2015, 3:08:33 PM12/4/15
to stan development mailing list, krzysztof...@gmail.com, a...@ariddell.org
On Friday, December 4, 2015 at 1:37:10 PM UTC-5, Allen B. Riddell wrote:
> Is there something standing in the way of creating a minimal
> protobuf-shim on top of the current C++ API for stanc? This is where I
> would start. I'd be willing to try this out with a fork/branch of
> PyStan.

I will have some time in the next week to give this a shot---just as a proof of concept so don't anyone get worried about making work for other people. I've never looked at pystan's
internals or even tried to build it from source so I'll do something stand-alone.

Bob Carpenter

unread,
Dec 4, 2015, 4:14:33 PM12/4/15
to stan...@googlegroups.com
Those Google docs are great. They even have variant
types (oneof). Thanks.

I don't understand how this is going to work for stanc.
The underlying lang/compiler.hpp has this interface:

input: string for program
output stream for writing messages

output: string for the C++ class for the program

side effects: write warning messages to the output stream.

The rest of the behavior of stanc in CmdStan or RStan or
PyStan is from the interface.

I like the idea of more structured errors. Unfortunately,
they're now being written directly to the stream as text
in a way that's plumbed right down to the low-level semantic
actions in lang/grammars/*_def.hpp.

So what's the protocol buffer interface going to look
like in terms of messages?

Is the idea that there'll be a stanc server somewhere
communicating via protocol buffers over sockets (or http or
whatever)?

Or is the idea to rewrite compiler.hpp so that what
gets passed in is a protocol buffer writer instead of
an output stream? I think an intermediate solution where
we refactor the output produced by the parser and code
generator the same way we're doing the rest of the interface
so that it would take more general callbacks with methods
to do the writing however they want. One such callback
could be protocol buffers.

- Bob
Thanks --- those
Definitely if there's code involved. Is there a branch already
going somewhere?

- Bob

Krzysztof Sakrejda

unread,
Dec 4, 2015, 4:36:46 PM12/4/15
to stan development mailing list
On Friday, December 4, 2015 at 4:14:33 PM UTC-5, Bob Carpenter wrote:
> Those Google docs are great. They even have variant
> types (oneof). Thanks.
>
> I don't understand how this is going to work for stanc.
> The underlying lang/compiler.hpp has this interface:
>
> input: string for program
> output stream for writing messages
>
> output: string for the C++ class for the program
>
> side effects: write warning messages to the output stream.
>
> The rest of the behavior of stanc in CmdStan or RStan or
> PyStan is from the interface.
>
> I like the idea of more structured errors. Unfortunately,
> they're now being written directly to the stream as text
> in a way that's plumbed right down to the low-level semantic
> actions in lang/grammars/*_def.hpp.
>
> So what's the protocol buffer interface going to look
> like in terms of messages?
>
> Is the idea that there'll be a stanc server somewhere
> communicating via protocol buffers over sockets (or http or
> whatever)?

So I'm enthusiastic about a stanc server as a prototype just
because protobuf and grpc (http://www.grpc.io/docs/
https://github.com/grpc/grpc/blob/release-0_11/examples/cpp/cpptutorial.md)
make it seem really straightforward.

>
> Or is the idea to rewrite compiler.hpp so that what
> gets passed in is a protocol buffer writer instead of
> an output stream?

I think Allen is more enthusiastic about writing a thin layer of
protobuf to make passing protobuf messages possible.

> I think an intermediate solution where
> we refactor the output produced by the parser and code
> generator the same way we're doing the rest of the interface
> so that it would take more general callbacks with methods
> to do the writing however they want. One such callback
> could be protocol buffers.

Yes, I think using this for streaming output could be a pretty
cool use of the writer refactor (and it's come up in a few
conversations but Michael suggested waiting till the writer
refactor was done).

So far the list of suggested protobuf-related test projects looks like:
1) stanc server
2) shim for interfaces (say over just stanc to start)
3) standardizing error messages
4) streaming output using the current writer refactor-ed code.
5) adding callbacks parallel to the writer refactor so that protobuf messages could be produced

Part of my goal for starting this discussion on the mailing list was
to see if we can agree on which items deserve priority.

(I'm happy to do a simple version of 1) just as a demo regardless since the stanc
interface is so straightforward...)

Krzysztof

Not until there's a goal for the code! :)

>
> - Bob

Bob Carpenter

unread,
Dec 4, 2015, 5:02:19 PM12/4/15
to stan...@googlegroups.com
Thanks --- that clears things up a lot in terms
of the space you're thinking about. I think all of
this is a good idea.

For (5), we'd just put write callbacks that wrote to
protocol buffers.

I think doing simple things first to get a handle for
how it works is a good idea. The design's going to
be tangled up in the refactor design, so we should
keep this in mind. I don't see any special problems
that writing to protocol buffers present --- in fact,
they solve many of the problems that other kinds of
writing (like to CSV files) have. I particularly like
that they can be heterogeneously typed containers.

- Bob

Allen B. Riddell

unread,
Dec 5, 2015, 4:32:03 AM12/5/15
to stan...@googlegroups.com
On 12/04, Bob Carpenter wrote:
> Zero-copy passing. How does that work? We need to
> get std::vector and Eigen::Matrix instances on the Stan
> side, both of which require copies from raw data
> as far as I know. Now I can believe you could "zero copy"
> a block of memory, like a pointer.
>

It just works in terms of blocks of memory. Here's an example from the API:

https://developers.google.com/protocol-buffers/docs/reference/cpp/google.protobuf.io.zero_copy_stream

We can just pass around blocks of continuous memory provided their
orientation is right for both Stan/Eigen and R/Python. The point here is
merely that Protocol Buffers will not get in our way if we figure out a
way to do this. This is rather impressive in itself, I think.

> The only reason not to do this now is that it'll all change
> again with the refactor, and I don't think Daniel or Michael
> want more work for that. So as long as you're happy having it
> on a branch until the Stan 3 refactor lands, there shouldn't
> be a problem.

This seems like a critical point. Can we prioritize finishing up the
refactor insofar as it touches calls to stanc? I think stanc is a fine
place to start finalizing the Stan 3 API in any event and doing so first
would also enable this protobuf experimentation.

Michael Betancourt

unread,
Dec 5, 2015, 6:42:54 AM12/5/15
to stan...@googlegroups.com
If people want to play with protocol buffers why not start with
an output.csv -> buffer translator just to provide an example
of how to work with the buffer API?

I would love to be working on new features, too, but this refactor
has to get done.

Krzysztof Sakrejda

unread,
Dec 5, 2015, 2:07:04 PM12/5/15
to stan development mailing list
For the moment I just made a repo under my own account b/c it's still pretty loosely thought out (github.com/sakrejda/servestan)... and missing the little bit that calls stanc/documentation etc...

Would it make sense to make a "proto" repository under stan-dev so that the various attempts at applying protobuf share the same set of .proto files (and they can get discussed or have issues independently of a specific project)?

Krzysztof

On Friday, December 4, 2015 at 5:02:19 PM UTC-5, Bob Carpenter wrote:
> Thanks --- that clears things up a lot in terms
> of the space you're thinking about. I think all of
> this is a good idea.
>
> For (5), we'd just put write callbacks that wrote to
> protocol buffers.
>
> I think doing simple things first to get a handle for
> how it works is a good idea. The design's going to
> be tangled up in the refactor design, so we should
> keep this in mind. I don't see any special problems
> that writing to protocol buffers present --- in fact,
> they solve many of the problems that other kinds of
> writing (like to CSV files) have. I particularly like
> that they can be heterogeneously typed containers.
>
> - Bob
>

Bob Carpenter

unread,
Dec 5, 2015, 2:33:44 PM12/5/15
to stan...@googlegroups.com

> On Dec 5, 2015, at 2:07 PM, Krzysztof Sakrejda <krzysztof...@gmail.com> wrote:
>
> For the moment I just made a repo under my own account b/c it's still pretty loosely thought out (github.com/sakrejda/servestan)... and missing the little bit that calls stanc/documentation etc...
>
> Would it make sense to make a "proto" repository under stan-dev so that the various attempts at applying protobuf share the same set of .proto files (and they can get discussed or have issues independently of a specific project)?

Depends what you're trying to do. The driving factor isn't
how well thought out the idea is --- it's where the feature
will eventually land.

If this is going to be a change in Stan, branch from
stan-dev/stan. If it's going to be another external interface
like CmdStan, create a new repo in stan-dev.

- Bob

Bob Carpenter

unread,
Dec 5, 2015, 2:37:55 PM12/5/15
to stan...@googlegroups.com
What kind of interface are you proposing for stanc?

And what exaclty are we talking about? There's an executable
named "stanc" in CmdStan, and then there's the compilation
behavior in R, which hits the same underlying lang/compiler.hpp
functionality.

I laid out the lowest-level internal interface a couple messages
ago.

- Bob

Allen B. Riddell

unread,
Dec 5, 2015, 3:38:39 PM12/5/15
to stan...@googlegroups.com
Perhaps I jumped the gun. I don't have a problem with the current stanc
API (by which I mean the RStan/PyStan call into lang/compiler.hpp):

In PyStan this is the Cython signature that wraps some C++ code
(duplicated from/in RStan) which calls stan::lang::compile

def stanc(bytes model_stancode, bytes model_name):
cdef PyStancResult result
c_stanc(model_stancode, model_name, result)
return {'status': result.status,
'msg': result.msg.decode('ascii'),
'model_cppname': result.model_cppname.decode('ascii'),
'cppcode': result.cppcode.decode('ascii')}

I can imagine this being replaced by some judicious use of Protocol
Buffers.

Perhaps that's not what Krzysztof had in mind. I imagine it's in the
ballpark.

Best,

Allen

Krzysztof Sakrejda

unread,
Dec 26, 2015, 10:35:06 PM12/26/15
to stan development mailing list
On Saturday, December 5, 2015 at 2:33:44 PM UTC-5, Bob Carpenter wrote:

Bob, could you take a look into the repository at github.com/sakrejda/protostan? I don't have the permissions to add
a new repo to stan-dev but I did set up a new repo that depends on
stan-dev/stan and stan-dev/math as submodules. There's a little README.md,
a wrapper around stan::lang::compile, a tests for the wrapper that matches the
test for stan::lang::compile, and a compile-run.sh that should be a complete recipe for compiling and running the (two) tests.

My questions about this are:

1) Does this make sense as a stan-dev repo? If so, could you make a stan-dev fork?
2) What should the namespace setup be like? At the moment it's stan::proto::function_name and I was expecting it to just be flat (so that that's where someone writing an interface would fine all the external API functionality) I'm open to doing something different, I have no experience with this.
3) Does the directory structure make sense? Again, I have little experience with making something other developers would find intuitive so I just monkeyed what Stan has (with the potential complication of code in multiple languages, not just C++).
4) I'm thinking of this as a sketch so if there's something I can do to flesh out the intent of the project I'm open to input.
5) I'm working on a writer_callback that would make sense in this context but I can't quite tell which parts of Stan are meant to be an "external" API (the stuff in "services" maybe?) So suggestions on which parts to wrap are also welcome.

Thanks for any pointers!

Krzysztof

>
> - Bob

Bob Carpenter

unread,
Dec 27, 2015, 10:36:33 PM12/27/15
to stan...@googlegroups.com
I took a look, see below.

Maybe Daniel, Michael and I can look at it while we're all here.
They've spent much more time looking at interface I/O than me.

Where it goes depends on whether we think of it as part of
Stan itself or an interface like CmdStan. It may wind up
being a bit of both. What are the licenses for the dependencies
for protocol buffers?

I'm afraid I don't understand what I'm looking at, for
example, in /proto/stanc.proto. Is that a protocol buffer
interface script? I've never used them before. What is
State? Is that some kind of return code enum? And cpp code is
what's produced? What's the 2, 3, and 4 for? I could guess a
default value for state, but cpp_code and messages are numbers.

I assume those binaries checked into protostan/test were put
there by mistake --- they're 40MB+.

And then do you check in all that autogenerated C++ code
in /src/cpp/proto/stanc.pb.h?

Where is the actual test code?

- Bob

Allen B. Riddell

unread,
Dec 28, 2015, 6:14:05 AM12/28/15
to stan...@googlegroups.com
On 12/27, Bob Carpenter wrote:
> I assume those binaries checked into protostan/test were put
> there by mistake --- they're 40MB+.
>
> And then do you check in all that autogenerated C++ code
> in /src/cpp/proto/stanc.pb.h?
>

Fixed in PR (https://github.com/sakrejda/protostan/pull/3)

> Where is the actual test code?
>

You can get a sense of what's going on by looking at two files:

- https://github.com/sakrejda/protostan/blob/master/src/cpp/protostan/lang/compiler.hpp
- https://github.com/sakrejda/protostan/blob/master/proto/stanc.proto

and the test file

- https://github.com/sakrejda/protostan/blob/master/src/cpp/test/stanc-test.cpp

I think these are the only substantive pieces of code at this point.

Krzysztof Sakrejda

unread,
Dec 28, 2015, 9:41:40 AM12/28/15
to stan development mailing list
On Sunday, December 27, 2015 at 10:36:33 PM UTC-5, Bob Carpenter wrote:
> I took a look, see below.

Thanks!



> Maybe Daniel, Michael and I can look at it while we're all here.
> They've spent much more time looking at interface I/O than me.
> Where it goes depends on whether we think of it as part of
> Stan itself or an interface like CmdStan. It may wind up
> being a bit of both.

There is a lot of complexity added with the protobuf dependencies
and the protobuf code generation so unless there's a compelling
reason I think it makes sense to keep it a separate repo. If
we find a compelling reason to merge things in the future that's
fine too.

> What are the licenses for the dependencies for protocol buffers?

I don't see any dependencies for protobuf (?)

> I'm afraid I don't understand what I'm looking at, for
> example, in /proto/stanc.proto. Is that a protocol buffer
> interface script? I've never used them before. What is
> State? Is that some kind of return code enum? And cpp code is
> what's produced? What's the 2, 3, and 4 for? I could guess a
> default value for state, but cpp_code and messages are numbers.

What's a proto file: the .proto file plays the same kind of role as
a .stan file in that it can be translated by the protobuf compiler
("protoc") into C++ (or other languages).

What's up with the numbers: protobuf makes you number your fields
and that has some implications for efficiency and backwards/forwards
compatibility and efficiency.

- Efficiency: items in a messages with field numbers under... 16
(or some small number like that, don't remember now) take less
storage space. I think this only really matters when you transmit
a LOT of really small messages.

- Compatibility: the generated code can be used to check whether a
field exists, so if you deprecate and remove a field but keep the fields
numbered (leaving a useless hole in the numbering) the code previously
generated from the .proto file can continue working (assuming it doesn't
require the presence of the deprecated field). If you do renumber
fields you break all the auto-generated code.

> I assume those binaries checked into protostan/test were put
> there by mistake --- they're 40MB+.
>
> And then do you check in all that autogenerated C++ code
> in /src/cpp/proto/stanc.pb.h?

I just left it in so you could see where it was going, but Allan made a pull request to clean this stuff up which I'm going to merge.

> Where is the actual test code?

src/cpp/protostan/lang/compiler.hpp has the wrapper
src/cpp/test/stanc-test.cpp has the few tests

Krzysztof

>
> - Bob

Bob Carpenter

unread,
Dec 28, 2015, 4:29:20 PM12/28/15
to stan...@googlegroups.com
But what I'm trying to understand is who you are expecting
to use this interface and for what. It's hard to even read
it without understanding what it's for.

By dependencies, I meant are there any libraries you need
to include and what are their licenses? Stan has dependencies
currently on Boost and Eigen, but nothing else. Is this going
to add new library dependencies? For example, who wrote the protobuf
compiler?

- Bob

Krzysztof Sakrejda

unread,
Dec 28, 2015, 8:18:06 PM12/28/15
to stan development mailing list
On Monday, December 28, 2015 at 4:29:20 PM UTC-5, Bob Carpenter wrote:
> But what I'm trying to understand is who you are expecting
> to use this interface and for what. It's hard to even read
> it without understanding what it's for.

Ok, let's pretend we needed an interface for R. The interface author
could deal with R -> C -> C++ and associated memory management.

As an alternative the interface author could write their interface code
around constructing protobuf messages following this guide:

https://cran.r-project.org/web/packages/RProtoBuf/vignettes/RProtoBuf-quickref.pdf

Then the step of calling Stan would involve only calling simple functions , passing protobuf messages as argument, and receiving protobuf messages in return. The vignette linked above show that, for the example message "message", to code for constructing it is as simple as:

message <- new( tutorial.Person, id = 0,
name = "Romain Francois",
email = "fran...@huh.org" )
message[[ "name" ]] <- "Romain"

Now if we pretend we wanted a website driven Stan interface written by someone who knows PHP, they could do the same kind of song and dance in PHP. Following
https://github.com/allegro/php-protobuf/#example here's an example of using PHP to construct a protobuf message (the .proto file is at the link):

<?php
require_once 'pb_proto_foo.php';

$foo = new Foo();
$foo->setBar(1);
$foo->setBaz('two');
$foo->appendSpam(3.0);
$foo->appendSpam(4.0);

$packed = $foo->serializeToString();

$foo->clear();

try {
$foo->parseFromString($packed);
} catch (Exception $ex) {
die('Upss.. there is a bug in this example');
}

$foo->dump();
?>

Anyway, this really limits the complexity of the actual external calls from any given language and should make it easy to write a first interface. Given the promises protobuf makes about efficiency and limiting copying I don't think it would be a bad first interface. I don't know if that vision will work out in the end but if Stan is successful enough to have interfaces to a dozen more languages I think this approach would limit the maintenance headaches. I recognize that these goals overlap with the Stan 3 goals but I don't know enough about Stan 3 goals to know how much overlap there is.

> By dependencies, I meant are there any libraries you need
> to include and what are their licenses? Stan has dependencies
> currently on Boost and Eigen, but nothing else. Is this going
> to add new library dependencies? For example, who wrote the protobuf
> compiler?

If you rolled it into stan itself there would be one dependency for the supporting protobuf library. The protobuf compiler license is pretty simple:
https://github.com/google/protobuf/blob/master/LICENSE

The key bit is:

"Code generated by the Protocol Buffer compiler is owned by the owner of the input file used when generating it. This code is not
standalone and requires a support library to be linked with it. This
support library is itself covered by the above license."

Sorry this is confusing, I only brought it back up here you
sounded interested in seeing the code. It'll only make more
sense once we figure out exactly what we want to wrap and
produce a functional example.

Bob Carpenter

unread,
Dec 28, 2015, 10:29:34 PM12/28/15
to stan...@googlegroups.com
Cool --- that's the BSD 3-clause license, just like we
use for Stan and the Stan math lib.

This is very tightly interconnected with the refactor
of the core Stan functionality. That's going to be
a C++ API.

Any protocol buffer interface would be layered on top of
the C++ API. I don't understand enough about protocol
buffers or the interface languages to understand if it
would be easier to connect to protocol buffers that
connected to the underlying C++ than it would be to connect
to the underlying C++.

- Bob

Allen B. Riddell

unread,
Dec 29, 2015, 6:36:32 AM12/29/15
to stan...@googlegroups.com
Hi Bob,

The protocol buffer interface to the Stan C++ API is a C API. Having a C
API for Stan makes writing an interface far easier.

There are two major applications I can imagine -- here I'll just echo
what Krzysztof said:

- Python, Julia, Go, R, etc. could interface with the C API without
needing to write any C or C++ code at all. In most of these languages
it's very simple to wrap C code but considerably harder to interface
with C++ code.
- ServerStan -- some sort of streaming, multiplexed HTTP2-based RPC
version of Stan in the cloud (using Google's gRPC, I would think).
Could be extremely cool. People could just install a thin client on
their computer. Having such a thing would make a browser-based Stan
very easy to do (the hard part would be the UI).

Best,

Allen

Bob Carpenter

unread,
Dec 29, 2015, 1:56:09 PM12/29/15
to stan...@googlegroups.com

> On Dec 29, 2015, at 6:36 AM, Allen B. Riddell <a...@ariddell.org> wrote:
>
> Hi Bob,
>
> The protocol buffer interface to the Stan C++ API is a C API.

I thought it was a pure protocol buffer API that could run in
any language with a protocol buffer library.

So I don't understand where C comes in. You seem to suggest
below that the interface writer (e.g., someone writing
a replacement for PyStan) will just use the interface
language (say Python).

That would mean everything from exceptions to
streaming output will be done with protocol buffers.

> Having a C
> API for Stan makes writing an interface far easier.

Is that true for R, too?

> There are two major applications I can imagine -- here I'll just echo
> what Krzysztof said:
>
> - Python, Julia, Go, R, etc. could interface with the C API without
> needing to write any C or C++ code at all. In most of these languages
> it's very simple to wrap C code but considerably harder to interface
> with C++ code.

You mean that Python would write Python code to call a protocol buffer
that hides all the C++ details? I just don't see where C comes into the picture.

> - ServerStan -- some sort of streaming, multiplexed HTTP2-based RPC
> version of Stan in the cloud (using Google's gRPC, I would think).
> Could be extremely cool. People could just install a thin client on
> their computer. Having such a thing would make a browser-based Stan
> very easy to do (the hard part would be the UI).

And affording the cycles! So you'd use Google's gRPC to connect
to a dockerized version of Stan? All these interfaces make my head
spin.

- Bob

Allen B. Riddell

unread,
Dec 29, 2015, 4:10:02 PM12/29/15
to stan...@googlegroups.com
On 12/29, Bob Carpenter wrote:
>
> > On Dec 29, 2015, at 6:36 AM, Allen B. Riddell <a...@ariddell.org> wrote:
> >
> > Hi Bob,
> >
> > The protocol buffer interface to the Stan C++ API is a C API.
>
> I thought it was a pure protocol buffer API that could run in
> any language with a protocol buffer library.

There are a couple of options here. Protocol buffers are a serialization
format with support in most languages. I'm intrigued by the option of
writing a shim (in C++ with a bunch of extern "C" functions accepting
and returning Protocol Buffer-formatted buffers) which could be used
directly by a foreign function library. Doing so could lighten PyStan
considerably. This approach is a bit different than the ServerStan idea
(which would communicate by passing protocol buffer messages over a
network socket).

>
> So I don't understand where C comes in. You seem to suggest
> below that the interface writer (e.g., someone writing
> a replacement for PyStan) will just use the interface
> language (say Python).
>
> That would mean everything from exceptions to
> streaming output will be done with protocol buffers.
>
> > Having a C
> > API for Stan makes writing an interface far easier.
>
> Is that true for R, too?
>

Maybe. In theory you might be able to use the built-in foreign function
interface instead of Rcpp.

I'm not exactly sure what will be easiest. It might be easier to run an
instance of ServerStan locally and have a thin client talk to that. In
that case PyStan could become a bundled distribution of a thin
client+ServerStan.

> > There are two major applications I can imagine -- here I'll just echo
> > what Krzysztof said:
> >
> > - Python, Julia, Go, R, etc. could interface with the C API without
> > needing to write any C or C++ code at all. In most of these languages
> > it's very simple to wrap C code but considerably harder to interface
> > with C++ code.
>
> You mean that Python would write Python code to call a protocol buffer
> that hides all the C++ details? I just don't see where C comes into the picture.
>
> > - ServerStan -- some sort of streaming, multiplexed HTTP2-based RPC
> > version of Stan in the cloud (using Google's gRPC, I would think).
> > Could be extremely cool. People could just install a thin client on
> > their computer. Having such a thing would make a browser-based Stan
> > very easy to do (the hard part would be the UI).
>
> And affording the cycles! So you'd use Google's gRPC to connect
> to a dockerized version of Stan? All these interfaces make my head
> spin.

Ok, so a public version of ServerStan would certainly have to include
some IP-address based rate limiting.
Reply all
Reply to author
Forward
0 new messages