Skip to content

Commit 4590053

Browse files
authored
libfaasm: add support for general S3 API (#126)
* libfaasm: add support for general s3 API * s3: add function to get number of buckets * s3: add remaining basic functions * nits: run clang-format * gh: bump minor code version * libfaasm: remove un-implemented symbols * s3: temporarily commit the workflow functions * wc: more functions * s3: untrack wc functions * s3: build functions as part of gha * func(demo): update chain_output function for new signature * func: separate threaded/non-threaded targets
1 parent 4d9f40c commit 4590053

17 files changed

+283
-16
lines changed

.env

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
SYSROOT_VERSION=0.5.0
2-
SYSROOT_CLI_IMAGE=faasm.azurecr.io/cpp-sysroot:0.5.0
1+
SYSROOT_VERSION=0.6.0
2+
SYSROOT_CLI_IMAGE=faasm.azurecr.io/cpp-sysroot:0.6.0
33
COMPOSE_PROJECT_NAME=cpp-dev

.github/workflows/tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
if: github.event.pull_request.draft == false
1818
runs-on: ubuntu-latest
1919
container:
20-
image: faasm.azurecr.io/cpp-sysroot:0.5.0
20+
image: faasm.azurecr.io/cpp-sysroot:0.6.0
2121
steps:
2222
# --- Update code ---
2323
- name: "Checkout code"

VERSION

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.5.0
1+
0.6.0

func/CMakeLists.txt

+1
Original file line numberDiff line numberDiff line change
@@ -74,4 +74,5 @@ add_subdirectory(dynlink)
7474
add_subdirectory(errors)
7575
add_subdirectory(mpi)
7676
add_subdirectory(omp)
77+
add_subdirectory(s3)
7778
add_subdirectory(threads)

func/demo/chain_output.cpp

+15-6
Original file line numberDiff line numberDiff line change
@@ -26,28 +26,37 @@ int main(int argc, char* argv[])
2626
unsigned int callIdB = faasmChain(otherB, nullptr, 0);
2727

2828
std::string expectedA = "expected A";
29-
std::string actualA;
30-
actualA.reserve(expectedA.size());
3129

3230
std::string expectedB = "longer expected B";
33-
std::string actualB;
34-
actualB.reserve(expectedB.size());
3531

32+
std::string actualA;
33+
char* actualABuf;
34+
int actualABufSize;
3635
unsigned int resA =
37-
faasmAwaitCallOutput(callIdA, actualA.c_str(), actualA.size());
36+
faasmAwaitCallOutput(callIdA, &actualABuf, &actualABufSize);
37+
actualA.assign(actualABuf, actualABuf + actualABufSize);
38+
39+
std::string actualB;
40+
char* actualBBuf;
41+
int actualBBufSize;
3842
unsigned int resB =
39-
faasmAwaitCallOutput(callIdB, actualB.c_str(), actualB.size());
43+
faasmAwaitCallOutput(callIdB, &actualBBuf, &actualBBufSize);
44+
actualB.assign(actualBBuf, actualBBuf + actualBBufSize);
4045

4146
if (resA != 0 || resB != 0) {
4247
printf("One or more chained calls failed: %i %i\n", resA, resB);
4348
return 1;
4449
}
4550

4651
if (actualA != expectedA) {
52+
printf(
53+
"Output mismatch: %s != %s\n", actualA.c_str(), expectedA.c_str());
4754
return 1;
4855
}
4956

5057
if (actualB != expectedB) {
58+
printf(
59+
"Output mismatch: %s != %s\n", actualB.c_str(), expectedB.c_str());
5160
return 1;
5261
}
5362

func/s3/CMakeLists.txt

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
set(FAASM_USER s3)
2+
3+
function(s3_func exec_name dir_path)
4+
faasm_func(${exec_name} ${dir_path})
5+
set(ALL_DEMO_FUNCS ${ALL_DEMO_FUNCS} ${exec_name} PARENT_SCOPE)
6+
endfunction(s3_func)
7+
8+
s3_func(get_num_buckets get_num_buckets.cpp)
9+
s3_func(list_buckets list_buckets.cpp)
10+
s3_func(get_num_keys get_num_keys.cpp)
11+
s3_func(list_keys list_keys.cpp)
12+
s3_func(add_key_bytes add_key_bytes.cpp)
13+
s3_func(get_key_bytes get_key_bytes.cpp)
14+
15+
# Custom target to group all the demo functions
16+
add_custom_target(s3_all_funcs DEPENDS ${ALL_DEMO_FUNCS})

func/s3/add_key_bytes.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
extern "C"
2+
{
3+
#include "faasm/host_interface.h"
4+
}
5+
6+
#include <faasm/faasm.h>
7+
#include <stdio.h>
8+
9+
int main(int argc, char* argv[])
10+
{
11+
// Get bucket and key from command line
12+
if (argc != 3) {
13+
printf("error: must invoke function with two arguments: bucketName "
14+
"keyName\n");
15+
return 1;
16+
}
17+
18+
char* bucketName = argv[1];
19+
char* keyName = argv[2];
20+
21+
// Get the bytes to add as input
22+
int inputSize = faasmGetInputSize();
23+
uint8_t keyBytes[inputSize];
24+
faasmGetInput(keyBytes, inputSize);
25+
26+
int ret =
27+
__faasm_s3_add_key_bytes(bucketName, keyName, (void*)keyBytes, inputSize);
28+
29+
return ret;
30+
}

func/s3/get_key_bytes.cpp

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
extern "C"
2+
{
3+
#include "faasm/host_interface.h"
4+
}
5+
6+
#include <faasm/faasm.h>
7+
#include <stdio.h>
8+
9+
int main(int argc, char* argv[])
10+
{
11+
// Get bucket and key from command line
12+
if (argc != 3) {
13+
printf("error: must invoke function with two arguments: bucketName "
14+
"keyName\n");
15+
return 1;
16+
}
17+
18+
char* bucketName = argv[1];
19+
char* keyName = argv[2];
20+
21+
uint8_t* keyBytes;
22+
int keyBytesLen;
23+
24+
int ret =
25+
__faasm_s3_get_key_bytes(bucketName, keyName, &keyBytes, &keyBytesLen);
26+
printf("Got %s/%s: %s\n", bucketName, keyName, (char*)keyBytes);
27+
faasmSetOutput((char*)keyBytes, keyBytesLen);
28+
29+
return ret;
30+
}

func/s3/get_num_buckets.cpp

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
extern "C"
2+
{
3+
#include "faasm/host_interface.h"
4+
}
5+
6+
#include <faasm/faasm.h>
7+
#include <stdio.h>
8+
#include <string>
9+
10+
int main(int argc, char* argv[])
11+
{
12+
int numBuckets = __faasm_s3_get_num_buckets();
13+
14+
printf("Got %i buckets!\n", numBuckets);
15+
16+
std::string numBucketsStr = std::to_string(numBuckets);
17+
faasmSetOutput(numBucketsStr.c_str(), numBucketsStr.size());
18+
19+
return 0;
20+
}

func/s3/get_num_keys.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
extern "C"
2+
{
3+
#include "faasm/host_interface.h"
4+
}
5+
6+
#include <faasm/faasm.h>
7+
#include <stdio.h>
8+
#include <string>
9+
10+
int main(int argc, char* argv[])
11+
{
12+
// Get the bucket name as an input
13+
int inputSize = faasmGetInputSize();
14+
char bucketName[inputSize];
15+
faasmGetInput((uint8_t*)bucketName, inputSize);
16+
17+
int numKeys = __faasm_s3_get_num_keys(bucketName);
18+
19+
printf("Bucket %s has %i keys!\n", bucketName, numKeys);
20+
21+
std::string numKeysStr = std::to_string(numKeys);
22+
faasmSetOutput(numKeysStr.c_str(), numKeysStr.size());
23+
24+
return 0;
25+
}

func/s3/list_buckets.cpp

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
extern "C"
2+
{
3+
#include "faasm/host_interface.h"
4+
}
5+
6+
#include <faasm/faasm.h>
7+
#include <stdio.h>
8+
#include <string.h>
9+
10+
int main(int argc, char* argv[])
11+
{
12+
int numBuckets = __faasm_s3_get_num_buckets();
13+
14+
char* bucketsBuffer[numBuckets];
15+
int bucketsBufferLens[numBuckets];
16+
__faasm_s3_list_buckets(bucketsBuffer, bucketsBufferLens);
17+
18+
int totalSize = 0;
19+
for (int i = 0; i < numBuckets; i++) {
20+
totalSize += bucketsBufferLens[i];
21+
}
22+
totalSize += numBuckets - 1;
23+
24+
// Prepare the output: instead of a newline use a '|' character
25+
char outBuffer[totalSize];
26+
27+
printf("Got %i buckets!\n", numBuckets);
28+
int offset = 0;
29+
for (int i = 0; i < numBuckets; i++) {
30+
strncpy(outBuffer + offset, bucketsBuffer[i], bucketsBufferLens[i]);
31+
offset += bucketsBufferLens[i];
32+
if (i < numBuckets - 1) {
33+
outBuffer[offset] = (char)'|';
34+
offset += 1;
35+
}
36+
printf("Bucket %i: %s\n", i, bucketsBuffer[i]);
37+
}
38+
39+
faasmSetOutput(outBuffer, totalSize);
40+
41+
return 0;
42+
}

func/s3/list_keys.cpp

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
extern "C"
2+
{
3+
#include "faasm/host_interface.h"
4+
}
5+
6+
#include <faasm/faasm.h>
7+
#include <stdio.h>
8+
#include <string.h>
9+
10+
int main(int argc, char* argv[])
11+
{
12+
// Get the bucket name as an input
13+
int inputSize = faasmGetInputSize();
14+
char bucketName[inputSize];
15+
faasmGetInput((uint8_t*)bucketName, inputSize);
16+
17+
int numKeys = __faasm_s3_get_num_keys(bucketName);
18+
19+
char* keysBuffer[numKeys];
20+
int keysBufferLens[numKeys];
21+
__faasm_s3_list_keys(bucketName, keysBuffer, keysBufferLens);
22+
23+
int totalSize = 0;
24+
for (int i = 0; i < numKeys; i++) {
25+
totalSize += keysBufferLens[i];
26+
}
27+
totalSize += numKeys - 1;
28+
29+
// Prepare the output: instead of a newline use a '|' character
30+
char outBuffer[totalSize];
31+
32+
printf("Bucket %s has %i keys!\n", bucketName, numKeys);
33+
int offset = 0;
34+
for (int i = 0; i < numKeys; i++) {
35+
strncpy(outBuffer + offset, keysBuffer[i], keysBufferLens[i]);
36+
offset += keysBufferLens[i];
37+
if (i < numKeys - 1) {
38+
outBuffer[offset] = (char)'|';
39+
offset += 1;
40+
}
41+
printf("Key %i: %s\n", i, keysBuffer[i]);
42+
}
43+
44+
faasmSetOutput(outBuffer, totalSize);
45+
46+
return 0;
47+
}

libfaasm/core.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,8 @@ unsigned int faasmAwaitCall(unsigned int messageId)
152152
}
153153

154154
unsigned int faasmAwaitCallOutput(unsigned int messageId,
155-
const char* output,
156-
long outputLen)
155+
char** output,
156+
int* outputLen)
157157
{
158158
return __faasm_await_call_output(messageId, output, outputLen);
159159
}

libfaasm/faasm/core.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ extern "C"
188188
* Gets the output from the given call into the buffer
189189
*/
190190
unsigned int faasmAwaitCallOutput(unsigned int messageId,
191-
const char* output,
192-
long outputLen);
191+
char** output,
192+
int* outputLen);
193193

194194
/**
195195
* Returns the python user

libfaasm/faasm/host_interface.h

+33-2
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ int __faasm_await_call(unsigned int messageId);
114114

115115
HOST_IFACE_FUNC
116116
int __faasm_await_call_output(unsigned int messageId,
117-
const char* output,
118-
long outputLen);
117+
char** output,
118+
int* outputLen);
119119

120120
HOST_IFACE_FUNC
121121
void __faasm_get_py_user(unsigned char* buffer, long bufferLen);
@@ -160,4 +160,35 @@ void __faasm_migrate_point(FaasmMigrateEntryPoint f, int arg);
160160

161161
HOST_IFACE_FUNC
162162
void __faasm_host_interface_test(int testNum);
163+
164+
// ----- S3 -----
165+
166+
HOST_IFACE_FUNC
167+
int __faasm_s3_get_num_buckets();
168+
169+
// Note that bucketsBuffer is, in reality, a char** populated by the host
170+
HOST_IFACE_FUNC
171+
void __faasm_s3_list_buckets(void* bucketsBuffer, int* bucketsBufferLens);
172+
173+
HOST_IFACE_FUNC
174+
int __faasm_s3_get_num_keys(const char* bucketName);
175+
176+
// Note that keysBuffer is, in reality, a char** populated by the host
177+
HOST_IFACE_FUNC
178+
void __faasm_s3_list_keys(const char* bucketName,
179+
void* keysBuffer,
180+
int* keysBufferLens);
181+
182+
HOST_IFACE_FUNC
183+
int __faasm_s3_add_key_bytes(const char* bucketName,
184+
const char* keyName,
185+
void* keyBuffer,
186+
int keyBufferLen);
187+
188+
// Note that keyBuffer is, in reality, a uint8_t** populated by the host
189+
HOST_IFACE_FUNC
190+
int __faasm_s3_get_key_bytes(const char* bucketName,
191+
const char* keyName,
192+
void* keyBuffer,
193+
int* keyBufferLen);
163194
#endif

libfaasm/libfaasm.imports

+8
Original file line numberDiff line numberDiff line change
@@ -42,5 +42,13 @@ __faasm_sm_critical_local_end
4242
# Migration
4343
__faasm_migrate_point
4444

45+
# S3
46+
__faasm_s3_get_num_buckets
47+
__faasm_s3_list_buckets
48+
__faasm_s3_get_num_keys
49+
__faasm_s3_list_keys
50+
__faasm_s3_add_key_bytes
51+
__faasm_s3_get_key_bytes
52+
4553
# Test
4654
__faasm_host_interface_test

tasks/func.py

+8
Original file line numberDiff line numberDiff line change
@@ -179,8 +179,16 @@ def local(ctx, clean=False, debug=False):
179179
"""
180180
Compile all functions used in the tests
181181
"""
182+
# Mixing users that use the threads sysroot and the non-threads sysroot
183+
# seems to give some rather obscure compilation errors, so just make sure
184+
# to separate them
185+
186+
# Non-threaded users
182187
user(ctx, "demo", clean, debug)
183188
user(ctx, "errors", clean, debug)
184189
user(ctx, "mpi", clean, debug)
190+
user(ctx, "s3", clean, debug)
191+
192+
# Threaded users
185193
user(ctx, "omp", clean, debug)
186194
user(ctx, "threads", clean, debug)

0 commit comments

Comments
 (0)