Accessing IList<T> inside Alea.Gpu.Default.For - gpgpu

I am trying to access values of System.Collections.Generic.IList<T> which is declared outside Alea.Gpu.Default.For.
[GpuManaged]
private void Evaluate_Caching(IList<TGenome> genomeList)
{
var gpu = Gpu.Default;
gpu.For(0, genomeList.Count - 1, i =>
{
TGenome genome = genomeList[i];
TPhenome phenome = (TPhenome)genome.CachedPhenome;
if (null == phenome)
{ // Decode the phenome and store a ref against the genome.
phenome = _genomeDecoder.Decode(genome);
genome.CachedPhenome = phenome;
}
if (null == phenome)
{ // Non-viable genome.
genome.EvaluationInfo.SetFitness(0.0);
genome.EvaluationInfo.AuxFitnessArr = null;
}
else
{
FitnessInfo fitnessInfo = _phenomeEvaluator.Evaluate(phenome);
genome.EvaluationInfo.SetFitness(fitnessInfo._fitness);
genome.EvaluationInfo.AuxFitnessArr = fitnessInfo._auxFitnessArr;
}
});
}
With reference to one of the questions asked earlier iterate-over-a-collection-of-custom-classes-with-alea-gpu I have also enabled <memory allowNonBlittableMemoryTransfer="true"/> in App.config.
However I am getting an error as
"Cannot get field "genomeList".
Possible reasons:
-> The field type is not supported.
-> In closure class, the field doesn't have [GpuParam] attribute.
Diagnostics:
-> Struct: ref(dyn{ i32 }(m:<Evaluate_Caching>b__0)):_O_
-> FieldName: genomeList
Source location stack:
-> in E:\_turingProjects\_csProjects\Gpu_Project\GpuParallelGenomeListEvaluator.cs(183,17-183,48)
-> at Evaluators.GpuParallelGenomeListEvaluator`2+<>c__DisplayClass17_0[SharpNeat.Genomes.Neat.NeatGenome,SharpNeat.Phenomes.IBlackBox].[Void <Evaluate_Caching>b__0(Int32)]
-> at Alea.Parallel.Device.DeviceFor.[Void Kernel(Int32, Int32, System.Action`1[System.Int32])]
-> at defining runtime64 (sm50,64bit)
Loading method as kernel:
-> Method: Alea.Parallel.Device.DeviceFor.[Void Kernel(Int32, Int32, System.Action`1[System.Int32])]
-> InstanceOpt: <None>
-> Argument.#0: 0
-> Argument.#1: 1999
-> Argument.#2: System.Action`1[System.Int32]
What could be the possible reason of error? What is the correct way to use values inside Gpu.For ?

Currently, AleaGPU only works with array. List usually require dynamic memory allocation, such as add element, which is not efficient in GPU.

Related

Flatmap throws compile time error while flattened nested Mono

Have below Method
private Mono<EventSlotBook> getTestEventSlotBook(EventUserAppt eventUserAppt){
Query query = new Query();
query.addCriteria(
new Criteria().andOperator(
Criteria.where("eventId").is(eventUserAppt.getEventId()),
Criteria.where("eventConfigId").is(eventUserAppt.getEventConfigId()),
Criteria.where("eventSlotId").is(eventUserAppt.getEventSlotId()),
Criteria.where("appointmentDate").in(eventUserAppt.getAppointmentDate()
)));
return this.reactiveMongoTemplate.findOne(query, EventSlotBook.class)
.flatMap(eventSlotExistingEntity -> {
if(eventSlotExistingEntity.getEventUsers() != null) {
eventSlotExistingEntity.getEventUsers().add(eventUserAppt.getEventUser());
}
return Mono.just(eventSlotExistingEntity);
})
.switchIfEmpty(getInitialTestEventSlotBook(eventUserAppt));
}
And above method called by
public Mono<EventSlotBookRequestDto> saveEventSlotBookFinal(Mono<EventSlotBookRequestDto> eventSlotBookRequestDtoMono){
log.info("Start::SaveEventSlotBook#######Final");
Mono<EventSlotBookRequestDto> eventDtoSaved =
eventSlotBookRequestDtoMono.map(AppUtils::dtoToEventUserApptEntity)
.flatMap(eventUserApptEntity -> getEventUserAppt(eventUserApptEntity))
.doOnNext(eventUserApptBeforeSave -> {
log.info("####BeforeSave::{}",eventUserApptBeforeSave);
})
.flatMap(eventUserApptRepository::save)
.doOnNext( eventUserApptAftereSave -> {
log.info("####AfterSave::{}",eventUserApptAftereSave);
})
.map(eventUserApptAfterSave -> getTestEventSlotBook(eventUserApptAfterSave)) -> IDE shows it returns Mono<Mono<EventSlotBoo>>
.flatMap(eventSlotBookrepository::save) --> Compile time error: o instance(s) of type variable(s) exist so that Mono<EventSlotBook> conforms to EventSlotBook
.map(eventSlotBooEntity -> AppUtils.entityToDto((EventSlotBook)eventSlotBooEntity));
log.info("End::SaveEventSlotBook#####Final");
return eventDtoSaved;
}
#Repository
public interface EventSlotBookRepository extends ReactiveMongoRepository<EventSlotBook,String> {
}
Not sure why .flatMap(eventSlotBookrepository::save) --> Compile time error: o instance(s) of type variable(s) exist so that Mono conforms to EventSlotBook it throws this error. flatMap expected flattened Mono<Mono> to EventSlotBook and save this data
ReactiveMongoRepository does not have a save method which would accept a Mono. It can only accept an instance of the entity type, so the following would work:
.flatMap(eventUserApptAfterSave -> getTestEventSlotBook(eventUserApptAfterSave)) // map changed to flatMap
.flatMap(eventSlotBookrepository::save)

How to cast elements in an instance of List with streams in Java 8?

Given the code:
public Statement methodCallByName(MethodDeclaration method, String string) {
List<ExpressionStatement> expressions = method.getBody().statements().stream()
.filter(s -> s instanceof ExpressionStatement)
.map(ExpressionStatement.class::cast)
.collect(Collectors.toList());
return null;
}
I have the following error in Eclipse Oxygen:
Notice that statements() returns a List according to JDT docs.
What is wrong?
The problem is caused by statements() returning the raw type List (see also What is a raw type and why shouldn't we use it?).
Raw types may not only provoke unchecked operations, but also limit the applicability of type inference.
You may fix it with
public Statement methodCallByName(MethodDeclaration method, String string) {
List<?> statements = method.getBody().statements();
List<ExpressionStatement> expressions = statements.stream()
.filter(s -> s instanceof ExpressionStatement)
.map(ExpressionStatement.class::cast)
.collect(Collectors.toList());
// ...
return null;
}
The conversion from the raw type List to a list of unknown element type List<?>, is the only type safe conversion we can do here. Since you are going to check and cast the elements anyway, that’s no restriction.
But note that you should try to be consistent. Use either
.filter(s -> s instanceof ExpressionStatement)
.map(s -> (ExpressionStatement)s)
or
.filter(ExpressionStatement.class::isInstance)
.map(ExpressionStatement.class::cast)

Iterate over Collected list in Java 8 GroupingBy

I have a List of Objects say List<Type1> that I have grouped using type.(using groupingBy)
Now I want to convert that Map> into Type2 that has both the list and the Id of that group.
class Type1{
int id;
int type;
String name;
}
class Type2{
int type;
List<Type1> type1List;
}
This is what I have written to achieve this:
myCustomList
.stream()
.collect(groupingBy(Type1::getType))
.entrySet()
.stream()
.map(type1Item -> new Type2() {
{
setType(type1Item.getKey());
setType1List(type1Item.getValue());
}
})
.collect(Collectors.toList());
This works perfectly. But I am trying to make the code even cleaner. Is there a way to avoid streaming this thing all over again and use some kind of flatmap to achieve this.
You can pass a finisher function to the collectingAndThen to get the work done after the formation of the initial map.
List<Type2> result = myCustomList.stream()
.collect(Collectors.collectingAndThen(Collectors.groupingBy(Type1::getType),
m -> m.entrySet().stream()
.map(e -> new Type2(e.getKey(), e.getValue()))
.collect(Collectors.toList())));
You should give Type2 a constructor of the form
Type2(int type, List<Type1> type1List) {
this.type = type;
this.type1List = type1List;
}
Then, you can write .map(type1Item -> new Type2(type1Item.getKey(), type1Item.getValue())) instead of
.map(type1Item -> new Type2() {
{
setType(type1Item.getKey());
setType1List(type1Item.getValue());
}
})
See also What is Double Brace initialization in Java?
In short, this creates a memory leak, as it creates a subclass of Type2 which captures the type1Item its entire lifetime.
But you can perform the conversion as part of the downstream collector of the groupingBy. This implies that you have to make the toList explicit, to combine it via collectingAndThen with the subsequent mapping:
Collection<Type2> collect = myCustomList
.stream()
.collect(groupingBy(Type1::getType,
collectingAndThen(toList(), l -> new Type2(l.get(0).getType(), l))))
.values();
If you really need a List, you can use
List<Type2> collect = myCustomList
.stream()
.collect(collectingAndThen(groupingBy(Type1::getType,
collectingAndThen(toList(), l -> new Type2(l.get(0).getType(), l))),
m -> new ArrayList<>(m.values())));
You can do as mentioned below:
type1.map( type1Item -> new Type2(
type1Item.getKey(), type1Item
)).collect(Collectors.toList());

How does control flow in Java8 collectors?

I am learning how to use Java 8 streams. While debugging this piece of code :
Collector<Person, StringJoiner, String> collector =
Collector.of(
() -> new StringJoiner(" | "),
(j,p) -> j.add(p.name.toLowerCase()),
StringJoiner::merge,
StringJoiner::toString);
System.out.println(persons.stream().collect(collector));
execution never reaches StringJoiner::merge or StringJoiner::toString. If I replace the combiner (StringJoiner::merge) with null, then the code throws null pointer exception. I am unable to follow.
Additional (related) question :
How can I add logging for debugging lambdas ? I tried adding braces for multi-line code blocks. This does not compile :
Collector<Person, StringJoiner, String> collector =
Collector.of(
() -> {
System.out.println("Supplier");
new StringJoiner(" | ")},
(j,p) -> j.add(p.name.toLowerCase()),
StringJoiner::merge,
StringJoiner::toString);
Here's your code with debug statements added (I replaced Person with String, but it doesn't change anything):
List<String> persons = Arrays.asList("John", "Mary", "Jack", "Jen");
Collector<String, StringJoiner, String> collector =
Collector.of(
() -> {
System.out.println("Supplier");
return new StringJoiner(" | ");
},
(j, p) -> {
System.out.println("Accumulator");
j.add(p.toLowerCase());
},
(stringJoiner, other) -> {
System.out.println("Combiner");
return stringJoiner.merge(other);
},
(stringJoiner) -> {
System.out.println("Finisher");
return stringJoiner.toString();
});
System.out.println(persons.stream().collect(collector));
Run it, and you'll see that the finisher is definitely called:
a StringJoiner is created by the supplier
all persons are added to the joiner
the finisher transforms the joiner to a String
The combiner, however, although required by the method of(), which checks for null, is only relevant if the collector is used on a parallel stream, and the stream really decides to split the work on multiple threads, thus using multiple joiners and combining them together.
To test that, you'll need a high number of persons in the collection, and a parallel stream instead of a sequential one:
List<String> persons = new ArrayList<>();
for (int i = 0; i < 1_000_000; i++) {
persons.add("p_" + i);
}
Collector<String, StringJoiner, String> collector =
Collector.of(
() -> {
System.out.println("Supplier");
return new StringJoiner(" | ");
},
(j, p) -> {
System.out.println("Accumulator");
j.add(p.toLowerCase());
},
(stringJoiner, other) -> {
System.out.println("Combiner");
return stringJoiner.merge(other);
},
(stringJoiner) -> {
System.out.println("Finisher");
return stringJoiner.toString();
});
System.out.println(persons.parallelStream().collect(collector));
The number of threads used is decided by the stream. And it can split the task done by one thread into yet two other threads in the middle if it thinks it's a good idea. Let's just assume it chooses to use 2:
two StringJoiners are created by the supplier, and a thread is allocated for each joiner
each thread adds half of the persons to its joiner
the two joiners are merged together by the combiner
the finisher transforms the merged joiner to a String

ES6 read-only enums that can map value to name

I would like to define an enum-like structure in JS, but have two requirements:
The values be read-only, i.e. no users can assign to them.
The values (0, 1, 2, ...) can be mapped back into the names (as with Java's name method)
The methods I know to create enums like this typically meet one requirement or the other, not both.
I've tried:
const MyEnum = {
a: 0,
b: 1,
c: 2
};
The enum itself is constant, but the values are still mutable and I can't map values back to names efficiently.
When writing an enum in Typescript, it outputs:
var MyEnum;
(function (MyEnum) {
MyEnum[MyEnum["a"] = 0] = "a";
MyEnum[MyEnum["b"] = 1] = "b";
MyEnum[MyEnum["c"] = 2] = "c";
})(MyEnum || (MyEnum = {}));
This can map both ways, but still doesn't have constant values.
The only option I've found that meets both requirements would be using getters on a class:
class MyEnum {
get a() {
return 0;
}
...
}
This method dramatically restricts the legal names and has a lot of overhead, especially in browsers that don't inline getters well (or can't).
#Shmiddty suggested freezing an object:
const MyEnum = Object.freeze({
a: 0,
b: 1,
c: 2
});
This meets the constant requirement well, but doesn't provide a great way to map values back to names.
I could write a helper that builds the reverse mapping like:
function reverseEnum(enum) {
Object.keys(enum).forEach(k => {
enum[enum[k]] = k;
});
}
But any kind of programmatic solution to generate the reverse mapping will run into problems if the original object is frozen or otherwise actually constant.
Is there a clean, concise solution to this in JS?
This does a pretty good job, IMHO.
function Enum(a){
let i = Object
.keys(a)
.reduce((o,k)=>(o[a[k]]=k,o),{});
return Object.freeze(
Object.keys(a).reduce(
(o,k)=>(o[k]=a[k],o), v=>i[v]
)
);
} // y u so terse?
const FOO = Enum({
a: 0,
b: 1,
c: "banana"
});
console.log(FOO.a, FOO.b, FOO.c); // 0 1 banana
console.log(FOO(0), FOO(1), FOO("banana")); // a b c
try {
FOO.a = "nope";
}
catch (e){
console.log(e);
}
I'd use a Map so that your enum values can be any type, rather than having them coerced into strings.
function Enum(obj){
const keysByValue = new Map();
const EnumLookup = value => keysByValue.get(value);
for (const key of Object.keys(obj)){
EnumLookup[key] = obj[key];
keysByValue.set(EnumLookup[key], key);
}
// Return a function with all your enum properties attached.
// Calling the function with the value will return the key.
return Object.freeze(EnumLookup);
}
If your enum is all strings, I'd also probably change one line to:
EnumLookup[key] = Symbol(obj[key]);
to ensure that the enum values are being used properly. Using just a string, you have no guarantee that some code hasn't simply passed a normal string that happens to be the same as one of your enum values. If your values are always strings or symbols, you could also swap out the Map for a simple object.
Just recently implemented an Es6 version that works quite well:
const k_VALUES = {}
export class ErrorCode {
constructor(p_apiCode, p_httpCode){
this.apiCode = p_apiCode;
this.httpCode = p_httpCode;
k_VALUES[p_apiCode] = this;
}
static create(p_apiCode){
if(k_VALUES[p_apiCode]){
return k_VALUES[p_apiCode];
}
return ErrorCode.UNKNOWN;
}
}
ErrorCode.UNKNOWN = new ErrorCode(0, 500);
ErrorCode.NOT_FOUND = new ErrorCode(-1000, 404);
ErrorCode.NOT_FOUND_EMAIL = new ErrorCode(-1001, 404);
ErrorCode.BAD_REQUEST = new ErrorCode(-1010, 404);
I wanted to implement a similar pattern as what we do with Java enums. This enables me to use a constructor to pass values. The constructor then freezes the ErrorCode object - nice and convenient.
Usage: first import your enum class...
import {ErrorCode} from "../common/services/errors/ErrorCode";
Now, after importing the enum class, access it like so:
if( errCode.includes(ErrorCode.BAD_REQUEST.apiCode) ){...}
PS> This is used in conjunction with a Webpack setup using Babel to convert our ES6 classes down for browser compatibility.

Resources