@@ -411,15 +411,17 @@ void CUDAEnvironmentDirectedGraphBuffers::syncDevice_async(detail::CUDAScatter&
411
411
}
412
412
}
413
413
if (requires_rebuild && vertex_count && edge_count) {
414
+ if (edge_count != h_edge_index_map.size ()) {
415
+ THROW exception::IDNotSet (" Unable to build graph, only %u/%u edges have been assigned both a source and destination, in CUDAEnvironmentDirectedGraphBuffers::syncDevice_async()" , edge_count, static_cast <unsigned int >(h_edge_index_map.size ()));
416
+ } else if (vertex_count != h_vertex_index_map.size ()) {
417
+ THROW exception::IDNotSet (" Unable to build graph, only %u/%u vertices have been assigned an ID, in CUDAEnvironmentDirectedGraphBuffers::syncDevice_async()" , vertex_count, static_cast <unsigned int >(h_vertex_index_map.size ()));
418
+ }
414
419
// Construct the vertex ID : index map
415
420
{
416
421
if (vertex_id_min == std::numeric_limits<unsigned int >::max () || vertex_id_max == std::numeric_limits<unsigned int >::min ()) {
417
422
THROW flamegpu::exception::IDOutOfBounds (" No IDs have been set, in CUDAEnvironmentDirectedGraphBuffers::syncDevice_async()" );
418
423
}
419
424
const unsigned int ID_RANGE = 1 + vertex_id_max - vertex_id_min;
420
- if (ID_RANGE < vertex_count) {
421
- THROW flamegpu::exception::IDNotSet (" Not all vertices have been assigned a unique ID, in CUDAEnvironmentDirectedGraphBuffers::syncDevice_async()" );
422
- }
423
425
if (d_vertex_index_map) {
424
426
gpuErrchk (flamegpu::detail::cuda::cudaFree (d_vertex_index_map));
425
427
}
@@ -625,7 +627,7 @@ void CUDAEnvironmentDirectedGraphBuffers::setVertexID(unsigned int vertex_index,
625
627
h_vertex_index_map.erase (static_cast <id_t *>(vb.h_ptr )[vertex_index]);
626
628
}
627
629
628
- // Add new vertex ID to host map (validate it's not already in us )
630
+ // Add new vertex ID to host map (validate it's not already in use )
629
631
const auto find = h_vertex_index_map.find (vertex_id);
630
632
if (find != h_vertex_index_map.end ()) {
631
633
THROW exception::IDCollision (" ID collision, %u has already been assigned to vertex at index %u, "
@@ -688,13 +690,118 @@ void CUDAEnvironmentDirectedGraphBuffers::setEdgeSourceDestination(unsigned int
688
690
// Require rebuild before use
689
691
markForRebuild ();
690
692
}
693
+ void CUDAEnvironmentDirectedGraphBuffers::setEdgeSource (unsigned int edge_index, id_t src_vertex_id) {
694
+ if (edge_index >= edge_count) {
695
+ THROW exception::OutOfBoundsException (" Edge index exceeds bounds %u >= %u, "
696
+ " in CUDAEnvironmentDirectedGraphBuffers::setEdgeSource()\n " , edge_index, edge_count);
697
+ } else if (src_vertex_id == ID_NOT_SET) {
698
+ THROW exception::IDOutOfBounds (" Source vertex ID of %u is not valid, "
699
+ " in CUDAEnvironmentDirectedGraphBuffers::setEdgeSource()\n " , ID_NOT_SET);
700
+ }
701
+ // Purge old edge src/dest from host map
702
+ auto & eb = edge_buffers.at (GRAPH_SOURCE_DEST_VARIABLE_NAME);
703
+ // Don't need to update buffer, src_dest is not stored as ID on device
704
+ id_t & edge_dest = static_cast <id_t *>(eb.h_ptr )[edge_index * 2 + 0 ];
705
+ id_t & edge_src = static_cast <id_t *>(eb.h_ptr )[edge_index * 2 + 1 ];
706
+
707
+ // Remove old edge from src map if it's complete
708
+ if (edge_src != ID_NOT_SET && edge_dest != ID_NOT_SET) {
709
+ h_edge_index_map.erase ({edge_src, edge_dest});
710
+ }
711
+
712
+ // Update edge's src dest in buffer
713
+ edge_src = src_vertex_id;
714
+ eb.ready = Buffer::Host;
715
+
716
+ // Add new edge ID to host map if it's complete
717
+ if (edge_src != ID_NOT_SET && edge_dest != ID_NOT_SET) {
718
+ // validate it's not already in use
719
+ const auto find = h_edge_index_map.find ({ edge_src, edge_dest });
720
+ if (find != h_edge_index_map.end ()) {
721
+ THROW exception::IDCollision (" Edge collision, an edge has already been assigned source %u dest %u at index %u, "
722
+ " in CUDAEnvironmentDirectedGraphBuffers::setEdgeSource()\n " , src_vertex_id, edge_dest, find->second );
723
+ }
724
+ h_edge_index_map.emplace (std::pair{src_vertex_id, edge_dest }, edge_index);
725
+ }
726
+
727
+ // Require rebuild before use
728
+ markForRebuild ();
729
+ }
730
+ void CUDAEnvironmentDirectedGraphBuffers::setEdgeDestination (unsigned int edge_index, id_t dest_vertex_id) {
731
+ if (edge_index >= edge_count) {
732
+ THROW exception::OutOfBoundsException (" Edge index exceeds bounds %u >= %u, "
733
+ " in CUDAEnvironmentDirectedGraphBuffers::setEdgeDestination()\n " , edge_index, edge_count);
734
+ } else if (dest_vertex_id == ID_NOT_SET) {
735
+ THROW exception::IDOutOfBounds (" Destination vertex ID of %u is not valid, "
736
+ " in CUDAEnvironmentDirectedGraphBuffers::setEdgeDestination()\n " , ID_NOT_SET);
737
+ }
738
+ // Purge old edge src/dest from host map
739
+ auto & eb = edge_buffers.at (GRAPH_SOURCE_DEST_VARIABLE_NAME);
740
+ // Don't need to update buffer, src_dest is not stored as ID on device
741
+ id_t & edge_dest = static_cast <id_t *>(eb.h_ptr )[edge_index * 2 + 0 ];
742
+ id_t & edge_src = static_cast <id_t *>(eb.h_ptr )[edge_index * 2 + 1 ];
743
+
744
+ // Update edge's src dest in buffer
745
+ if (edge_src != ID_NOT_SET && edge_dest != ID_NOT_SET) {
746
+ h_edge_index_map.erase ({edge_src, edge_dest});
747
+ }
748
+
749
+ // Update edge's src dest in buffer
750
+ edge_dest = dest_vertex_id;
751
+ eb.ready = Buffer::Host;
752
+
753
+ // Add new edge ID to host map if it's complete
754
+ if (edge_src != ID_NOT_SET && edge_dest != ID_NOT_SET) {
755
+ // validate it's not already in use
756
+ const auto find = h_edge_index_map.find ({ edge_src, edge_dest });
757
+ if (find != h_edge_index_map.end ()) {
758
+ THROW exception::IDCollision (" Edge collision, an edge has already been assigned source %u dest %u at index %u, "
759
+ " in CUDAEnvironmentDirectedGraphBuffers::setEdgeDestination()\n " , edge_src, edge_dest, find->second );
760
+ }
761
+ h_edge_index_map.emplace (std::pair{ edge_src, edge_dest }, edge_index);
762
+ }
763
+
764
+ // Require rebuild before use
765
+ markForRebuild ();
766
+ }
691
767
unsigned int CUDAEnvironmentDirectedGraphBuffers::getEdgeIndex (id_t src_vertex_id, id_t dest_vertex_id) const {
692
768
const auto find = h_edge_index_map.find ({src_vertex_id, dest_vertex_id});
693
769
if (find == h_edge_index_map.end ()) {
694
770
THROW exception::InvalidID (" No edge found with source %u, dest %u, in CUDAEnvironmentDirectedGraphBuffers::getEdgeIndex()\n " , src_vertex_id, dest_vertex_id);
695
771
}
696
772
return find->second ;
697
773
}
774
+ id_t CUDAEnvironmentDirectedGraphBuffers::getSourceVertexID (unsigned int edge_index, cudaStream_t stream) const {
775
+ if (edge_index >= edge_count) {
776
+ THROW exception::OutOfBoundsException (" Edge index exceeds bounds %u >= %u, "
777
+ " in CUDAEnvironmentDirectedGraphBuffers::getSourceVertexID()\n " , edge_index, edge_count);
778
+ }
779
+ // Purge old edge src/dest from host map
780
+ auto & eb = edge_buffers.at (GRAPH_SOURCE_DEST_VARIABLE_NAME);
781
+ eb.updateHostBuffer (edge_count, stream);
782
+ const unsigned int vertex_index = static_cast <id_t *>(eb.h_ptr )[edge_index * 2 + 1 ];
783
+ if (vertex_index == ID_NOT_SET)
784
+ return vertex_index;
785
+ auto & vb = vertex_buffers.at (GRAPH_SOURCE_DEST_VARIABLE_NAME);
786
+ vb.updateHostBuffer (vertex_count, stream);
787
+ return static_cast <id_t *>(vb.h_ptr )[vertex_index];
788
+ }
789
+ id_t CUDAEnvironmentDirectedGraphBuffers::getDestinationVertexID (unsigned int edge_index, cudaStream_t stream) const {
790
+ if (edge_index >= edge_count) {
791
+ THROW exception::OutOfBoundsException (" Edge index exceeds bounds %u >= %u, "
792
+ " in CUDAEnvironmentDirectedGraphBuffers::getDestinationVertexID()\n " , edge_index, edge_count);
793
+ }
794
+ // Purge old edge src/dest from host map
795
+ auto & eb = edge_buffers.at (GRAPH_SOURCE_DEST_VARIABLE_NAME);
796
+ eb.updateHostBuffer (edge_count, stream);
797
+ // Don't need to update buffer, src_dest is not stored as ID on device
798
+ const unsigned int vertex_index = static_cast <id_t *>(eb.h_ptr )[edge_index * 2 + 0 ];
799
+ if (vertex_index == ID_NOT_SET)
800
+ return vertex_index;
801
+ auto & vb = vertex_buffers.at (GRAPH_SOURCE_DEST_VARIABLE_NAME);
802
+ vb.updateHostBuffer (vertex_count, stream);
803
+ return static_cast <id_t *>(vb.h_ptr )[vertex_index];
804
+ }
698
805
699
806
unsigned int CUDAEnvironmentDirectedGraphBuffers::createIfNotExistVertex (id_t vertex_id, const cudaStream_t stream) {
700
807
if (vertex_id == ID_NOT_SET) {
0 commit comments