Skip to content

Commit 31ea984

Browse files
committed
Many small improvements and fixes. Temperature is no longer constant + many type fixes
1 parent 04eae9a commit 31ea984

File tree

4 files changed

+51
-46
lines changed

4 files changed

+51
-46
lines changed

include/graphblas/algorithms/simulated_annealing_re.hpp

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,8 @@ namespace grb {
7474
/*
7575
* Do a Parallel Tempering pass.
7676
* This means exchanging states at low temperature with states at higher temperature.
77-
* To make the code simpler, this will be done by exchanging the temperatures instead.
7877
*
79-
* TODO: Fix this documentation.
78+
* TODO: Complete this documentation.
8079
*
8180
* @param[in,out] states On input: initial states.
8281
* @param[in,out] energies The initial energy of each state.
@@ -101,18 +100,22 @@ namespace grb {
101100
pt(
102101
std::vector< grb::Vector< StateType, backend > > &states,
103102
grb::Vector< EnergyType, backend > &energies,
104-
const grb::Vector< TempType, backend > &betas
103+
const grb::Vector< TempType, backend > &betas,
104+
const int seed = 42
105105
){
106106

107107
const size_t n_replicas = states.size();
108108
// const size_t s = spmd<>::pid();
109109
// const size_t nprocs = spmd<>::nprocs();
110+
std::srand( seed );
110111
grb::RC rc = grb::SUCCESS;
112+
std::minstd_rand rng ( seed );
113+
std::exponential_distribution< EnergyType > rand ( 1.0 );
111114

112115
for( size_t i = n_replicas - 1 ; i > 0 ; --i ){
113116
const EnergyType de = ( energies[ i ] - energies[ i-1 ]) * (betas[ i ] - betas[ i-1 ]);
114117

115-
if( de >= 0 || std::rand() < RAND_MAX * internal::exp( de ) ){
118+
if( -rand( rng ) < de ){
116119
std::swap( states[i], states[i-1] );
117120
std::swap( energies[i], energies[i-1] );
118121
}
@@ -136,7 +139,8 @@ namespace grb {
136139
pt(
137140
std::vector< grb::Vector< StateType, backend > > &states,
138141
grb::Vector< EnergyType, backend > &energies,
139-
const grb::Vector< TempType, backend > &betas
142+
const grb::Vector< TempType, backend > &betas,
143+
const int seed = 42
140144
){
141145
static_assert( backend != grb::BSP1D );
142146
// static_assert( grb::_GRB_BACKEND == grb::BSP1D );
@@ -151,29 +155,30 @@ namespace grb {
151155
assert( grb::size(energies) == n_replicas );
152156
assert( grb::size(betas) == n_replicas );
153157
#endif
158+
std::minstd_rand rng ( seed + s );
159+
std::exponential_distribution< EnergyType > rand ( 1.0 );
154160
struct data {
155161
EnergyType e;
156162
TempType b;
157-
int r;
163+
EnergyType r;
158164
};
159165
grb::Vector< StateType, backend > s0 ( n );
160166
grb::Vector< StateType, backend > s1 ( n );
161167
grb::set( s0, static_cast< StateType >( 0 ) );
162168
grb::set( s1, static_cast< StateType >( 0 ) );
163169

164-
165170
struct data msg[ 2 ];
166171
rc = rc ? rc : grb::resize( s0, n );
167172
rc = rc ? rc : grb::resize( s1, n );
168173
if( rc != grb::SUCCESS ) return rc;
169-
int rand = std::rand();
174+
const auto myrand = -rand( rng );
170175

171176
for( size_t si = nprocs ; rc == grb::SUCCESS && si > 0; --si ){
172177
if( si-1 == s ){
173178
for( size_t i = n_replicas - 1 ; i > 0 ; --i ){
174179
const EnergyType de = ( energies[ i ] - energies[ i-1 ]) * (betas[ i ] - betas[ i-1 ]);
175180

176-
if( de >= 0 || std::rand() < RAND_MAX * internal::exp( de ) ){
181+
if( -rand( rng ) < de ){
177182
std::swap( states[i], states[i-1] );
178183
std::swap( energies[i], energies[i-1] );
179184
}
@@ -186,7 +191,7 @@ namespace grb {
186191
grb::set( s0, states[ n_replicas - 1 ] );
187192
msg[ 0 ].e = energies[ n_replicas - 1 ];
188193
msg[ 0 ].b = betas[ n_replicas - 1 ];
189-
msg[ 0 ].r = rand;
194+
msg[ 0 ].r = myrand;
190195
}
191196
if( si == 1 ) continue;
192197

@@ -216,9 +221,8 @@ namespace grb {
216221

217222
const EnergyType de = ( msg[ 1 ].e - msg[ 0 ].e ) * ( msg[ 1 ].b - msg[ 0 ].b );
218223

219-
if( rc == grb::SUCCESS && ( de >= 0 || msg[ 0 ].r < RAND_MAX * internal::exp( de ) ) ){
224+
if( rc == grb::SUCCESS && ( msg[ 0 ].r < de ) ){
220225
if( si == s+1 ){
221-
222226
rc = rc ? rc : grb::set( states[ n_replicas - 1 ], s0 );
223227
rc = rc ? rc : grb::setElement(energies, msg[ 0 ].e, n_replicas - 1 );
224228
}else if( si == s+2 ){
@@ -294,6 +298,7 @@ namespace grb {
294298
){
295299

296300
const size_t s = spmd<>::pid();
301+
const size_t n_procs = spmd<>::nprocs();
297302
const size_t n_replicas = states.size();
298303
const size_t n = grb::size(states[0]);
299304
(void) n;
@@ -337,7 +342,7 @@ namespace grb {
337342
} // n_replicas
338343
if( rc == SUCCESS && use_pt ){
339344
// do a Parallel Tempering move
340-
rc = pt< backend >( states, energies, betas );
345+
rc = pt< backend >( states, energies, betas, i_sweep*n_procs + s );
341346
}
342347
#ifndef NDEBUG
343348
if( s == 0 ) {
@@ -355,6 +360,7 @@ namespace grb {
355360
if( rc == SUCCESS ){
356361
rc = rc ? rc : grb::collectives<>::allreduce(
357362
best_energy, grb::operators::min< EnergyType >() );
363+
// TODO: update best state to match best energy
358364
}
359365

360366
return rc;
@@ -481,8 +487,6 @@ namespace grb {
481487
*
482488
* states should be a vector of already initialized and filled dense grb::Vector.
483489
*
484-
* TODO: expand and complete documentation
485-
*
486490
* Warning: This function allocates $O(n)$ memory for temporary vectors.
487491
*
488492
* @param[in,out] states On input: initial (dense) states.
@@ -536,7 +540,6 @@ namespace grb {
536540
(void) s;
537541
grb::RC rc = grb::SUCCESS;
538542

539-
assert( grb::size(states[0]) == n );
540543
assert( grb::nnz(states[0]) == n ); // state is dense
541544
assert( states.size() == n_replicas );
542545

@@ -576,21 +579,20 @@ namespace grb {
576579

577580
grb::Vector< QType, backend > h ( n );
578581
grb::Vector< QType, backend > rand ( n );
579-
grb::Vector< StateType, backend > delta ( n );
580-
grb::Vector< EnergyType, backend > dn ( n );
582+
grb::Vector< QType, backend > delta ( n );
583+
grb::Vector< QType, backend > dn ( n );
581584
grb::Vector< bool, backend > accept ( n );
582-
std::srand( static_cast<unsigned>( seed ) );
583585
std::minstd_rand rng ( seed ); // minstd_rand or std::mt19937
584586

585-
grb::resize( h, n );
586-
grb::resize( rand, n );
587-
grb::resize( delta, n );
588-
grb::resize( dn, n );
589-
grb::resize( accept, n );
587+
rc = rc ? rc : grb::resize( h, n );
588+
rc = rc ? rc : grb::resize( rand, n );
589+
rc = rc ? rc : grb::resize( delta, n );
590+
rc = rc ? rc : grb::resize( dn, n );
591+
rc = rc ? rc : grb::resize( accept, n );
590592

591593
std::vector< grb::Vector< bool, backend > > masks ;
592594
rc = rc ? rc : matrix_partition< descr >( masks, couplings, h, rand, seed );
593-
grb::clear(h);
595+
rc = rc ? rc : grb::clear(h);
594596
constexpr auto dense_descr = descr | grb::descriptors::dense;
595597

596598
auto sweep_data = std::tie(
@@ -632,7 +634,9 @@ namespace grb {
632634
const size_t n = grb::size( state );
633635
EnergyType delta_energy = static_cast< EnergyType >(0.0);
634636
grb::RC rc = grb::SUCCESS;
635-
(void) n;
637+
638+
assert( grb::nnz(state) == n ); // state has to be dense!
639+
assert( grb::nnz(local_fields) == n );
636640

637641
if( !empty_local_fields) {
638642
rc = rc ? rc : grb::set< descr >( h, local_fields );
@@ -644,7 +648,7 @@ namespace grb {
644648
std::exponential_distribution< EnergyType > rand_gen ( beta );
645649
for( size_t i = 0 ; i < n; ++i ){
646650
const auto rnd = -rand_gen( rng );
647-
grb::setElement( rand, rnd, i );
651+
rc = rc ? rc : grb::setElement( rand, rnd, i );
648652
}
649653

650654
const grb::operators::leq< EnergyType > leq_operator;

tests/smoke/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ add_grb_executables( simulated_annealing_re_from_mpi simulated_annealing_re_from
150150
)
151151

152152
add_grb_executables( simulated_annealing_re_ising simulated_annealing_re_ising.cpp
153-
BACKENDS reference reference_omp bsp1d hybrid hyperdags nonblocking
153+
BACKENDS reference reference_omp hyperdags nonblocking
154154
ADDITIONAL_LINK_LIBRARIES test_utils_headers
155155
)
156156

tests/smoke/simulated_annealing_re_from_mpi.cpp

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -287,8 +287,8 @@ EnergyType get_energy(
287287
assert( n == grb::size( state ) );
288288
assert( n == grb::ncols( couplings ) );
289289
assert( n == grb::nrows( couplings ) );
290-
grb::resize( tmp, n );
291290
grb::RC rc = grb::SUCCESS;
291+
rc = rc ? rc : grb::resize( tmp, n );
292292
EnergyType energy = 0.0;
293293
constexpr auto dense_descr = descr | grb::descriptors::dense;
294294

@@ -318,21 +318,18 @@ EnergyType sequential_sweep_immediate(
318318
const grb::Vector< JType, backend >&,
319319
grb::Vector< JType, backend >&,
320320
grb::Vector< JType, backend >&,
321-
grb::Vector< IOType, backend >&,
321+
grb::Vector< JType, backend >&,
322322
const std::vector< grb::Vector< bool, backend > >&,
323-
grb::Vector< EnergyType, backend >&,
323+
grb::Vector< JType, backend >&,
324324
grb::Vector< bool, backend >&,
325325
std::minstd_rand&
326326
> &data
327327
){
328328
const size_t s = spmd<>::pid();
329329
const Ring ring = Ring();
330+
constexpr auto dense_descr = descr | grb::descriptors::dense;
330331
(void) s;
331332

332-
grb::RC rc = grb::SUCCESS;
333-
const size_t n = grb::size( state );
334-
assert( grb::nnz(state) == n ); // state has to be dense!
335-
336333
EnergyType delta_energy = static_cast< EnergyType >(0.0);
337334
const auto &couplings = std::get<0>(data);
338335
const auto &local_fields = std::get<1>(data);
@@ -344,20 +341,25 @@ EnergyType sequential_sweep_immediate(
344341
auto &accept = std::get<7>(data);
345342
auto &rng = std::get<8>(data);
346343

344+
grb::RC rc = grb::SUCCESS;
345+
const size_t n = grb::size( state );
346+
assert( grb::nnz(state) == n ); // state has to be dense!
347+
assert( grb::nnz(local_fields) == n );
348+
347349
rc = rc ? rc : grb::wait();
348350
rc = rc ? rc : grb::resize( h, n );
349351
rc = rc ? rc : grb::resize( rand, n );
350352
rc = rc ? rc : grb::resize( delta, n );
351353
rc = rc ? rc : grb::resize( dn, n );
352354
rc = rc ? rc : grb::resize( accept, n );
353355

354-
rc = rc ? rc : grb::set< descr >( h, local_fields );
355-
rc = rc ? rc : grb::mxv< descr >( h, couplings, state , ring );
356+
rc = rc ? rc : grb::set< dense_descr >( h, local_fields );
357+
rc = rc ? rc : grb::mxv< dense_descr >( h, couplings, state , ring );
356358

357359
std::exponential_distribution< EnergyType > rand_gen ( beta );
358360
for( size_t i = 0 ; i < n; ++i ){
359-
const auto rnd = -rand_gen( rng );
360-
grb::setElement( rand, rnd, i );
361+
const auto rnd = rand_gen( rng );
362+
rc = rc ? rc : grb::setElement( rand, rnd, i );
361363
}
362364

363365
const grb::operators::leq< EnergyType > leq_operator;
@@ -423,9 +425,9 @@ template<
423425
const grb::Vector< JType, backend >&,
424426
grb::Vector< JType, backend >&,
425427
grb::Vector< JType, backend >&,
426-
grb::Vector< IOType, backend >&,
428+
grb::Vector< JType, backend >&,
427429
const std::vector< grb::Vector< bool, backend > >&,
428-
grb::Vector< EnergyType, backend >&,
430+
grb::Vector< JType, backend >&,
429431
grb::Vector< bool, backend >&,
430432
std::minstd_rand&
431433
>,
@@ -623,7 +625,7 @@ void grbProgram(
623625
grb::Vector< EnergyType, internal_backend > energies( n_replicas );
624626
grb::Vector< EnergyType, internal_backend > tmp_energy( n );
625627
for ( size_t r = 0; rc == grb::SUCCESS && r < n_replicas; ++r ) {
626-
rc = rc ? rc : grb::setElement( betas, static_cast< JType >(10.0), r );
628+
rc = rc ? rc : grb::setElement( betas, static_cast< JType >( 10.0 / ( n_replicas * s + r + 1) ), r );
627629
rc = rc ? rc : grb::setElement( energies, get_energy( J, h, states[r], tmp_energy ), r );
628630
}
629631

@@ -644,9 +646,9 @@ void grbProgram(
644646
grb::Vector< JType, internal_backend > temp_h ( n );
645647
grb::Vector< JType, internal_backend > temp_log_rand ( n );
646648
grb::Vector< IOType, internal_backend > best_state ( n );
647-
grb::Vector< EnergyType, internal_backend > temp_dn ( n );
649+
grb::Vector< JType, internal_backend > temp_dn ( n );
648650
grb::Vector< bool, internal_backend > temp_accept ( n );
649-
grb::Vector< IOType, internal_backend > temp_delta ( n );
651+
grb::Vector< JType, internal_backend > temp_delta ( n );
650652

651653
// build masks, we'll use two of the above temporary vectors
652654
std::vector< grb::Vector< bool, internal_backend > > masks;

tests/smoke/simulated_annealing_re_ising.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -469,12 +469,11 @@ void grbProgram(
469469
#endif
470470
}
471471

472-
473472
// also make betas vector os size n_replicas and initialize with 10.0
474473
grb::Vector< JType > betas( n_replicas );
475474
grb::Vector< EnergyType > energies( n_replicas );
476475
for ( size_t r = 0; rc == grb::SUCCESS && r < n_replicas; ++r ) {
477-
rc = rc ? rc : grb::setElement( betas, static_cast< JType >(10.0), r );
476+
rc = rc ? rc : grb::setElement( betas, static_cast< JType >( n_replicas / (r+1) ), r );
478477
// rc = rc ? rc : grb::setElement( energies, get_energy( J, h, states[r], tmp_energy ), r );
479478
}
480479
assert( rc == grb::SUCCESS );

0 commit comments

Comments
 (0)