Skip to content

Commit d5a57ba

Browse files
committed
feat: test e2e for realm-backend
1 parent 346f986 commit d5a57ba

10 files changed

Lines changed: 92 additions & 64 deletions

.proj.toml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,10 @@ has-cuda-benchmarks = false
7272

7373
[targets.realm-backend]
7474
type = "lib"
75-
tests = false
76-
benchmarks = false
75+
has-cpu-only-tests = true
76+
has-cpu-only-benchmarks = false
77+
has-cuda-tests = true
78+
has-cuda-benchmarks = false
7779

7880
[targets.models]
7981
type = "lib"

lib/realm-backend/include/realm-backend/model_training_instance.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ struct ModelTrainingInstance {
2828
PerLayerElapsedTime forward();
2929
PerLayerElapsedTime backward();
3030
void update();
31-
void write_loss_tensor_to_host(float *host_ptr);
31+
GenericTensorAccessorR get_loss_tensor_accessor() const;
3232
};
3333

3434
} // namespace FlexFlow

lib/realm-backend/include/realm-backend/realm_allocator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,6 @@
88

99
namespace FlexFlow {
1010

11-
struct RealmAllocatorImpl;
12-
1311
struct RealmAllocatorImpl : public IAllocator {
1412
RealmAllocatorImpl() = delete;
1513
RealmAllocatorImpl(RealmAllocatorImpl const &) = delete;
@@ -20,6 +18,8 @@ struct RealmAllocatorImpl : public IAllocator {
2018
void *allocate(size_t) override;
2119
void deallocate(void *) override;
2220

21+
DeviceType get_allocation_device_type() const override;
22+
2323
private:
2424
std::unordered_map<void *, Realm::RegionInstance> ptrs;
2525
Realm::Processor proc;

lib/realm-backend/include/realm-backend/realm_task_argument_accessor.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#ifndef _FLEXFLOW_REALM_BACKEND_REALM_TASK_ARGUMENT_ACCESSOR_H
22
#define _FLEXFLOW_REALM_BACKEND_REALM_TASK_ARGUMENT_ACCESSOR_H
33

4-
#include "local-execution/task_argument_accessor.h"
54
#include "realm-backend/realm_allocator.h"
65
#include "task-spec/slot_tensor_type_id.dtg.h"
6+
#include "task-spec/task_argument_accessor.h"
77
#include <unordered_map>
88
#include <variant>
99

lib/realm-backend/include/realm-backend/realm_tensor_backing.struct.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ name = "RealmTensorBacking"
33
features = [
44
"eq",
55
"fmt",
6-
"hash"
76
]
87

98
includes = [
@@ -15,9 +14,7 @@ includes = [
1514
]
1615

1716
src_includes = [
18-
"utils/hash/unordered_map.h",
1917
"utils/fmt/unordered_map.h",
20-
"utils/hash/vector.h",
2118
"utils/fmt/vector.h",
2219
]
2320

lib/realm-backend/src/model_training_instance.cc

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "pcg/computation_graph.h"
22
#include "pcg/optimizer_attrs.h"
33
#include "realm-backend/model_training_instance.h"
4+
#include "kernels/format_accessor_contents.h"
45
#include "utils/containers/reversed.h"
56

67
namespace FlexFlow {
@@ -39,6 +40,13 @@ PerLayerElapsedTime ModelTrainingInstance::backward() {
3940
this->logit_tensor,
4041
this->label_tensor);
4142

43+
gradient_tensor_t loss_tensor =
44+
this->training_backing.realm_tensor_backing.tensor_gradient_mapping.at(
45+
this->logit_tensor);
46+
GenericTensorAccessorW loss_tensor_backing =
47+
this->training_backing.realm_tensor_backing.tensor_backings.at(
48+
TensorTypeVariant{loss_tensor});
49+
4250
PerLayerElapsedTime per_layer_elapsed_time;
4351
std::unordered_map<layer_guid_t, Future<float>>
4452
per_layer_elapsed_time_future;
@@ -73,14 +81,19 @@ void ModelTrainingInstance::update() {
7381
this->optimizer_attrs);
7482
}
7583

76-
void ModelTrainingInstance::write_loss_tensor_to_host(float *host_ptr) {
84+
GenericTensorAccessorR ModelTrainingInstance::get_loss_tensor_accessor() const {
85+
GenericTensorAccessorW logit_tensor_backing = this->training_backing
86+
.realm_tensor_backing.tensor_backings.at(TensorTypeVariant{this->logit_tensor});
87+
88+
7789
gradient_tensor_t loss_tensor =
78-
this->training_backing.realm_tensor_backing
79-
.tensor_gradient_mapping.at(this->logit_tensor);
90+
this->training_backing.realm_tensor_backing.tensor_gradient_mapping.at(
91+
this->logit_tensor);
8092
GenericTensorAccessorW loss_tensor_backing =
8193
this->training_backing.realm_tensor_backing.tensor_backings.at(
8294
TensorTypeVariant{loss_tensor});
83-
write_to_host_float_ptr(loss_tensor_backing, host_ptr);
95+
96+
return read_only_accessor_from_write_accessor(loss_tensor_backing);
8497
}
8598

8699
} // namespace FlexFlow

lib/realm-backend/src/realm_allocator.cc

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ void RealmAllocatorImpl::deallocate(void *ptr) {
3636
}
3737
}
3838

39+
DeviceType RealmAllocatorImpl::get_allocation_device_type() const {
40+
return DeviceType::GPU;
41+
}
42+
3943
Allocator create_realm_memory_allocator(Processor proc) {
4044
return Allocator::create<RealmAllocatorImpl>(proc);
4145
}

lib/realm-backend/src/realm_task_argument_accessor.cc

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,16 @@ GenericTensorAccessor RealmTaskArgumentAccessor::get_tensor(
2424
auto tensor_backing = std::get<GenericTensorAccessorW>(
2525
this->tensor_slots_backing.at(slot_tensor_type));
2626
if (priv == Permissions::RO) {
27-
GenericTensorAccessorR readonly_tensor_backing = {
28-
tensor_backing.data_type, tensor_backing.shape, tensor_backing.ptr};
27+
GenericTensorAccessorR readonly_tensor_backing =
28+
read_only_accessor_from_write_accessor(tensor_backing);
2929
return readonly_tensor_backing;
3030
} else if (priv == Permissions::RW || priv == Permissions::WO) {
3131
return tensor_backing;
3232
} else {
3333
throw mk_runtime_error(fmt::format("Unhandled privilege mode {}", priv));
3434
}
3535
}
36+
3637
VariadicGenericTensorAccessor RealmTaskArgumentAccessor::get_variadic_tensor(
3738
slot_id_t slot, Permissions priv, TensorType tensor_type) const {
3839
SlotTensorTypeId slot_tensor_type = SlotTensorTypeId{slot, tensor_type};
@@ -43,7 +44,7 @@ VariadicGenericTensorAccessor RealmTaskArgumentAccessor::get_variadic_tensor(
4344
for (GenericTensorAccessorW const &tensor_backing :
4445
variadic_tensor_backing) {
4546
readonly_variadic_tensor_backing.push_back(
46-
{tensor_backing.data_type, tensor_backing.shape, tensor_backing.ptr});
47+
read_only_accessor_from_write_accessor(tensor_backing));
4748
}
4849
return readonly_variadic_tensor_backing;
4950
} else if (priv == Permissions::RW || priv == Permissions::WO) {

lib/realm-backend/src/realm_training_backing.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
#include "kernels/allocation.h"
22
#include "local-execution/loss_functions.h"
33
#include "local-execution/optimizer.h"
4-
#include "local-execution/task_signature_impl.h"
54
#include "pcg/computation_graph.dtg.h"
65
#include "pcg/computation_graph.h"
76
#include "pcg/optimizer_attrs.h"
87
#include "realm-backend/realm_tensor_backing.h"
98
#include "task-spec/op_task_to_task_invocation.h"
109
#include "task-spec/runtime_arg_config.h"
1110
#include "task-spec/task_invocation.h"
11+
#include "task-spec/task_signature_impl.h"
1212
#include "utils/containers/contains.h"
1313
#include "utils/containers/contains_key.h"
1414
#include "utils/containers/get_only.h"
Lines changed: 58 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1-
#include "kernels/managed_ff_stream.h"
2-
#include "kernels/managed_per_device_ff_handle.h"
1+
#include "kernels/compare_tensor_accessors.h"
2+
#include "kernels/format_accessor_contents.h"
3+
#include "kernels/tensor_accessor_reductions.h"
4+
#include "kernels/test_utils.h"
35
#include "local-execution/allocated_tensors.h"
46
#include "realm-backend/realm_allocator.h"
57
#include "realm-backend/realm_training_backing.h"
@@ -14,20 +16,21 @@
1416
using namespace ::FlexFlow;
1517
using namespace Realm;
1618

17-
bool did_loss_decrease(float *first_epoch, float *last_epoch, int batch_size) {
18-
for (int i = 0; i < batch_size; i++) {
19-
if (first_epoch[i] < last_epoch[i]) {
20-
return false;
21-
}
22-
}
23-
return true;
19+
bool did_loss_decrease(GenericTensorAccessorR const &first_epoch,
20+
GenericTensorAccessorR const &last_epoch) {
21+
Allocator cpu_allocator = create_local_cpu_memory_allocator();
22+
23+
return tensor_accessor_all(
24+
compare_tensor_accessors_le(last_epoch, first_epoch, cpu_allocator));
2425
}
2526

2627
void top_level_task(const void *args, size_t arglen, const void *userdata,
2728
size_t userlen, Realm::Processor p) {
2829
// initialize runtime
2930
ManagedFFStream managed_stream{};
30-
ManagedPerDeviceFFHandle managed_handle = initialize_single_gpu_handle();
31+
ManagedPerDeviceFFHandle managed_handle = initialize_single_gpu_handle(
32+
/*workSpaceSize=*/1024 * 1024,
33+
/*allowTensorOpMathConversion=*/true);
3134
std::vector<Processor> worker_procs;
3235
std::vector<Allocator> allocators;
3336
Machine::ProcessorQuery pq = Machine::ProcessorQuery(Machine::get_machine())
@@ -42,36 +45,37 @@ void top_level_task(const void *args, size_t arglen, const void *userdata,
4245
LossTensorSource loss_tensor_source;
4346
loss_tensor_t label_tensor = loss_tensor_source.new_loss_tensor();
4447

45-
nonnegative_int batch_size = 10_n;
46-
nonnegative_int data_dim = 16_n;
47-
nonnegative_int hidden_dim = 32_n;
48-
nonnegative_int output_dim = 1_n;
48+
positive_int batch_size = 10_p;
49+
positive_int data_dim = 16_p;
50+
positive_int hidden_dim = 32_p;
51+
positive_int output_dim = 1_p;
4952

53+
TensorShape input_tensor_shape = TensorShape{
54+
TensorDims{FFOrdered{batch_size, data_dim}}, DataType::FLOAT};
5055
TensorShape output_tensor_shape = TensorShape{
51-
TensorDims{FFOrdered<nonnegative_int>{batch_size, output_dim}},
52-
DataType::FLOAT};
56+
TensorDims{FFOrdered{batch_size, output_dim}}, DataType::FLOAT};
5357

54-
GenericTensorAccessorW label_tensor_backing =
55-
allocators[0].allocate_tensor(output_tensor_shape);
56-
AllocatedTensors allocated_tensors = AllocatedTensors{
57-
{{TensorTypeVariant{label_tensor}, label_tensor_backing}}, {}, {}};
58+
GenericTensorAccessorW label_tensor_backing = create_random_filled_accessor_w(
59+
output_tensor_shape, allocators[0]);
5860

5961
// construct computation graph
6062
ComputationGraph computation_graph = make_empty_computation_graph();
6163

62-
TensorShape input_tensor_shape = TensorShape{
63-
TensorDims{FFOrdered<nonnegative_int>{batch_size, data_dim}},
64-
DataType::FLOAT};
65-
6664
TensorShape weight_shape_1 = TensorShape{
67-
TensorDims{FFOrdered<nonnegative_int>{data_dim, hidden_dim}},
68-
DataType::FLOAT};
65+
TensorDims{FFOrdered{data_dim, hidden_dim}}, DataType::FLOAT};
6966
TensorShape weight_shape_2 = TensorShape{
70-
TensorDims{FFOrdered<nonnegative_int>{hidden_dim, output_dim}},
71-
DataType::FLOAT};
67+
TensorDims{FFOrdered{hidden_dim, output_dim}}, DataType::FLOAT};
68+
69+
GenericTensorAccessorW weight_1_backing = create_random_filled_accessor_w(
70+
weight_shape_1, allocators[0]);
71+
GenericTensorAccessorW weight_2_backing = create_random_filled_accessor_w(
72+
weight_shape_2, allocators[0]);
7273

7374
LayerAddedResult inputs_layer =
7475
add_input_layer_with_grad(computation_graph, input_tensor_shape);
76+
tensor_guid_t input_tensor_guid = get_only(inputs_layer.outputs);
77+
GenericTensorAccessorW input_tensor_backing = create_random_filled_accessor_w(
78+
input_tensor_shape, allocators[0]);
7579

7680
LayerAddedResult weights_layer_1 = add_layer(
7781
computation_graph,
@@ -80,6 +84,7 @@ void top_level_task(const void *args, size_t arglen, const void *userdata,
8084
std::nullopt},
8185
{},
8286
{});
87+
tensor_guid_t weight_1_tensor_guid = get_only(weights_layer_1.outputs);
8388

8489
LayerAddedResult weights_layer_2 = add_layer(
8590
computation_graph,
@@ -88,13 +93,14 @@ void top_level_task(const void *args, size_t arglen, const void *userdata,
8893
std::nullopt},
8994
{},
9095
{});
96+
tensor_guid_t weight_2_tensor_guid = get_only(weights_layer_2.outputs);
9197

9298
LayerAddedResult linear_operator_1 = add_layer(
9399
computation_graph,
94100
LayerAttrs{ComputationGraphOpAttrs{LinearAttrs{hidden_dim,
95101
/*use_bias=*/false,
96102
DataType::FLOAT,
97-
Activation::RELU,
103+
std::nullopt,
98104
std::nullopt}},
99105
std::nullopt},
100106
inputs_layer.outputs,
@@ -105,7 +111,7 @@ void top_level_task(const void *args, size_t arglen, const void *userdata,
105111
LayerAttrs{ComputationGraphOpAttrs{LinearAttrs{output_dim,
106112
/*use_bias=*/false,
107113
DataType::FLOAT,
108-
Activation::RELU,
114+
std::nullopt,
109115
std::nullopt}},
110116
std::nullopt},
111117
linear_operator_1.outputs,
@@ -130,6 +136,17 @@ void top_level_task(const void *args, size_t arglen, const void *userdata,
130136
GradientTensorSource gradient_tensor_source;
131137
OptimizerTensorSource optimizer_tensor_source;
132138

139+
AllocatedTensors allocated_tensors = AllocatedTensors{
140+
/*tensor_type_backings=*/{
141+
{TensorTypeVariant{label_tensor}, label_tensor_backing},
142+
{TensorTypeVariant{input_tensor_guid}, input_tensor_backing},
143+
{TensorTypeVariant{weight_1_tensor_guid}, weight_1_backing},
144+
{TensorTypeVariant{weight_2_tensor_guid}, weight_2_backing},
145+
},
146+
/*gradient_mapping=*/{},
147+
/*optimizer_mapping*/ {},
148+
};
149+
133150
{
134151
printf("\nRunning test %d: E2ETest...\n", 1);
135152
RealmTrainingBacking realm_training_backing = RealmTrainingBacking(
@@ -141,32 +158,26 @@ void top_level_task(const void *args, size_t arglen, const void *userdata,
141158
realm_training_backing, logit_tensor, label_tensor, loss_attrs, optimizer_attrs
142159
};
143160

161+
Allocator cpu_allocator = create_local_cpu_memory_allocator();
162+
144163
int num_epochs = 5;
145-
int num_samples = batch_size.unwrap_nonnegative();
146-
std::vector<float *> loss_values(num_epochs);
164+
std::vector<GenericTensorAccessorR> loss_values;
147165

148166
for (int i = 0; i < num_epochs; i++) {
149167
model_training_instance.forward();
150168
model_training_instance.backward();
151169
model_training_instance.update();
152-
float *host_loss_ptr = new float[num_samples];
153-
model_training_instance.write_loss_tensor_to_host(host_loss_ptr);
154-
loss_values[i] = host_loss_ptr;
170+
loss_values.push_back(copy_tensor_accessor_r(
171+
model_training_instance.get_loss_tensor_accessor(), cpu_allocator));
155172
}
156173

157174
// Assert that each sample in the batch has a lower loss in last epoch than
158175
// the first epoch
159-
float *first_epoch = loss_values[0];
160-
float *last_epoch = loss_values[num_epochs - 1];
161-
if(did_loss_decrease(
162-
first_epoch, last_epoch, batch_size.unwrap_nonnegative())) {
163-
printf("passed\n");
164-
} else {
165-
printf("failed\n");
166-
}
176+
GenericTensorAccessorR first_epoch_loss = loss_values.at(0);
177+
178+
GenericTensorAccessorR last_epoch = loss_values.back();
167179

168-
for (int i = 0; i < num_epochs; i++) {
169-
delete[] loss_values[i];
170-
}
180+
assert(did_loss_decrease(first_epoch_loss, last_epoch));
181+
printf("passed\n");
171182
}
172-
}
183+
}

0 commit comments

Comments
 (0)